-
Notifications
You must be signed in to change notification settings - Fork 1
Add propel-docs: an Astro documentation site for @makeplane/propel #233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
f0b43b8
Add design spec for the propel-docs Astro app
sriramveeraghanta f4fd2c1
Add implementation plan for the propel-docs Astro app
sriramveeraghanta 10162ce
Scaffold apps/propel-docs Astro app
sriramveeraghanta aa038a0
Ignore Astro build cache (.astro) across the workspace
sriramveeraghanta 12a489b
Wire Tailwind v4 + propel design tokens into propel-docs
sriramveeraghanta 346767a
Add layouts, sidebar nav, and installation page to propel-docs
sriramveeraghanta 1b953bd
Add props-table/demo plumbing and the Button doc page
sriramveeraghanta 02a17a9
Resolve propel via built dist in docs check/build, not tsconfig sourc…
sriramveeraghanta 837ab3b
Fix props-schema propel-root resolution for the production build
sriramveeraghanta 2d2f54d
Add Input Field doc page
sriramveeraghanta e030d0b
Add Select doc page
sriramveeraghanta 2078264
Add Dialog doc page
sriramveeraghanta 7b1e188
Add Table doc page
sriramveeraghanta 824d68c
Add Accordion doc page
sriramveeraghanta 856e599
Fix formatting/lint issues across propel-docs
sriramveeraghanta 70cb2bc
Restore @ts-check pragma to first line of astro.config.mjs
sriramveeraghanta efccbf1
Add PropsTable build-time warning and app README with deploy notes
sriramveeraghanta cda0789
Format docs/superpowers spec + plan to satisfy the oxfmt CI gate
sriramveeraghanta 8749016
Address PR review: memoize props parsing, type CodeBlock lang
sriramveeraghanta ee27ea5
Build propel before the workspace check in CI
sriramveeraghanta 3476567
Address PR review: dev-safe props cache + sidebar aria-current
sriramveeraghanta a0a7e1f
Gate props cache on NODE_ENV, not import.meta.env
sriramveeraghanta b3d1ee9
chore: remove docs
sriramveeraghanta File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # @makeplane/propel-docs | ||
|
|
||
| The documentation site for `@makeplane/propel`'s components. Built with Astro 7, | ||
| React islands (via `@astrojs/react`), and MDX for the component pages, styled | ||
| with propel's own Tailwind v4 tokens (`@makeplane/propel/styles`). | ||
|
|
||
| ## Commands | ||
|
|
||
| Run these from the repo root: | ||
|
|
||
| - `pnpm --filter @makeplane/propel-docs dev` — starts the dev server. In dev | ||
| mode, `astro.config.mjs` aliases `@makeplane/propel/components/*` and | ||
| `@makeplane/propel/styles` directly to propel's `src`, so editing a propel | ||
| component hot-reloads this site instantly — no propel build needed. | ||
| - `pnpm --filter @makeplane/propel-docs build` — production build. This first | ||
| runs `vp pack` on `@makeplane/propel` (to produce its `dist`), then runs | ||
| `astro build`, so the site resolves propel through its real, published | ||
| `dist` exports — the same way a consumer of the package would. | ||
| - `pnpm --filter @makeplane/propel-docs typecheck` — runs `astro check` (this | ||
| also packs propel first, for the same reason as `build`). | ||
| - `pnpm --filter @makeplane/propel-docs preview` — serves the built `dist` | ||
| output locally for a final check before deploying. | ||
|
|
||
| ## IMPORTANT: the deploy seam | ||
|
|
||
| The production build resolves `@makeplane/propel` through its built `dist`, | ||
| and `packages/propel/dist` is gitignored — it is not committed. Any CI or | ||
| Cloudflare build **must build propel before the site**. Use this package's | ||
| `build` script (`pnpm --filter @makeplane/propel-docs build`, which packs | ||
| propel first) rather than invoking `astro build` directly. A bare | ||
| `astro build` on a fresh checkout will fail to resolve | ||
| `@makeplane/propel/components/*`, since no `dist` exists yet. | ||
|
|
||
| ## Deployment placeholders | ||
|
|
||
| `astro.config.mjs`'s `site` and `wrangler.jsonc`'s `account_id` / `routes` are | ||
| intentional TODO placeholders, to be filled in once a real domain and | ||
| Cloudflare account are assigned. The sitemap integration (`@astrojs/sitemap`) | ||
| reads `site` to generate absolute URLs, so update `site` and rebuild once the | ||
| domain is set. | ||
|
|
||
| ## Adding a component page | ||
|
|
||
| 1. Create `src/demos/<name>/<variant>.tsx` — a small React demo that imports | ||
| only from `@makeplane/propel/components/<name>` and `lucide-react`, and | ||
| passes every required prop. | ||
| 2. Create `src/pages/components/<name>.mdx` following the existing pages: | ||
| frontmatter with `layout: ~/layouts/ComponentLayout.astro` plus `title` and | ||
| `description`; import each demo twice (once as the live component with | ||
| `client:visible`, once with a `?raw` suffix for the source snippet); | ||
| render it inside `<ComponentExample>`, add an "Installation" snippet, and | ||
| render `<PropsTable parts={[{ source, component }]} />` for the props | ||
| table. | ||
| 3. Add the page's entry (`slug`, `title`, `description`) to | ||
| `src/lib/components-registry.ts`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // @ts-check | ||
|
|
||
| import { resolve } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
|
|
||
| import mdx from "@astrojs/mdx"; | ||
| import react from "@astrojs/react"; | ||
| import sitemap from "@astrojs/sitemap"; | ||
| import tailwindcss from "@tailwindcss/vite"; | ||
| import { defineConfig } from "astro/config"; | ||
|
|
||
| const __dirname = fileURLToPath(new URL(".", import.meta.url)); | ||
|
|
||
| // Dev-mode alias to propel's real source, so editing a component hot-reloads | ||
| // this docs site without needing `vp pack --watch` running in parallel. | ||
| // Production builds resolve `@makeplane/propel` through its normal workspace | ||
| // package + dist exports instead (no alias). | ||
| const isDev = process.argv.includes("dev"); | ||
| const propelSrc = resolve(__dirname, "../../packages/propel/src"); | ||
|
|
||
| export default defineConfig({ | ||
| // TODO: replace with the real deployed domain once one is assigned. | ||
| site: "https://propel-docs.example.com", | ||
| integrations: [mdx(), react(), sitemap()], | ||
| vite: { | ||
| plugins: [tailwindcss()], | ||
| resolve: isDev | ||
| ? { | ||
| alias: [ | ||
| { | ||
| find: /^@makeplane\/propel\/components\/(.*)$/, | ||
| replacement: resolve(propelSrc, "components/$1/index.tsx"), | ||
| }, | ||
| { | ||
| find: "@makeplane/propel/styles", | ||
| replacement: resolve(propelSrc, "styles/propel.css"), | ||
| }, | ||
| ], | ||
| } | ||
| : undefined, | ||
| }, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "name": "@makeplane/propel-docs", | ||
| "version": "0.0.0", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "dev": "astro dev", | ||
| "build": "vp run @makeplane/propel#build && astro build", | ||
| "preview": "astro preview", | ||
| "typecheck": "vp run @makeplane/propel#build && astro check" | ||
| }, | ||
| "dependencies": { | ||
| "@astrojs/mdx": "^7.0.3", | ||
| "@astrojs/react": "^6.0.1", | ||
| "@astrojs/sitemap": "^3.7.3", | ||
| "@makeplane/propel": "workspace:*", | ||
| "@tailwindcss/vite": "catalog:", | ||
| "astro": "^7.0.9", | ||
| "lucide-react": "catalog:", | ||
| "react": "^19.2.7", | ||
| "react-dom": "^19.2.7", | ||
| "tailwindcss": "catalog:" | ||
| }, | ||
| "devDependencies": { | ||
| "@astrojs/check": "^0.9.9", | ||
| "@types/node": "catalog:", | ||
| "@types/react": "^19.2.17", | ||
| "@types/react-dom": "^19.2.3", | ||
| "react-docgen-typescript": "^2.4.0", | ||
| "typescript": "catalog:", | ||
| "wrangler": "^4.110.0" | ||
| } | ||
| } |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| --- | ||
| import { Code } from "astro:components"; | ||
| import type { CodeLanguage } from "astro"; | ||
|
|
||
| type Props = { | ||
| code: string; | ||
| lang?: CodeLanguage; | ||
| }; | ||
|
|
||
| const { code, lang = "tsx" } = Astro.props; | ||
| --- | ||
|
|
||
| <Code code={code.trimEnd()} lang={lang} theme="github-dark" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| --- | ||
| import CodeBlock from "~/components/CodeBlock.astro"; | ||
|
|
||
| type Props = { | ||
| code: string; | ||
| }; | ||
|
|
||
| const { code } = Astro.props; | ||
| --- | ||
|
|
||
| <div class="overflow-hidden rounded-lg border border-subtle"> | ||
| <div class="flex items-center justify-center border-b border-subtle bg-surface-1 p-8"> | ||
| <slot /> | ||
| </div> | ||
| <details class="group"> | ||
| <summary class="cursor-pointer list-none px-4 py-2 text-sm text-secondary select-none"> | ||
| <span class="group-open:hidden">Show code</span> | ||
| <span class="hidden group-open:inline">Hide code</span> | ||
| </summary> | ||
| <CodeBlock code={code} /> | ||
| </details> | ||
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| --- | ||
| import type { PropItemType } from "react-docgen-typescript"; | ||
|
|
||
| import { getComponentDoc } from "~/lib/props-schema"; | ||
|
|
||
| type Part = { | ||
| source: string; | ||
| component: string; | ||
| }; | ||
|
|
||
| type Props = { | ||
| parts: Part[]; | ||
| }; | ||
|
|
||
| const { parts } = Astro.props; | ||
|
|
||
| // `shouldExtractLiteralValuesFromEnum` (props-schema.ts) puts a string-literal union's members in | ||
| // `type.value` (each `{ value: '"primary"' }`) while `type.name` stays the generic `"enum"` — join | ||
| // them back into the `"primary" | "secondary" | …` form so the table shows the real union, not the | ||
| // bare word "enum". | ||
| function formatType(type: PropItemType): string { | ||
| if (type.name === "enum" && Array.isArray(type.value)) { | ||
| return type.value.map((entry: { value: string }) => entry.value).join(" | "); | ||
| } | ||
| return type.name; | ||
| } | ||
| --- | ||
|
|
||
| <div class="flex flex-col gap-8"> | ||
| { | ||
| parts.map(({ source, component }) => { | ||
| const doc = getComponentDoc(source, component); | ||
| if (!doc || Object.keys(doc.props).length === 0) { | ||
| console.warn( | ||
| `[PropsTable] No component doc found for "${component}" at source "${source}" — the props table will be empty. Check the source path (relative to packages/propel/src) and the exported component name.`, | ||
| ); | ||
| } | ||
| const props = doc ? Object.values(doc.props) : []; | ||
| return ( | ||
| <div> | ||
| <h3 class="mb-3 font-mono text-sm font-medium text-primary">{component}</h3> | ||
| <div class="overflow-x-auto rounded-lg border border-subtle"> | ||
| <table class="w-full border-collapse text-sm"> | ||
| <thead> | ||
| <tr class="border-b border-subtle bg-surface-1 text-left"> | ||
| <th class="px-4 py-2 font-medium text-secondary">Prop</th> | ||
| <th class="px-4 py-2 font-medium text-secondary">Type</th> | ||
| <th class="px-4 py-2 font-medium text-secondary">Required</th> | ||
| <th class="px-4 py-2 font-medium text-secondary">Description</th> | ||
| </tr> | ||
| </thead> | ||
| <tbody> | ||
| {props.map((prop) => ( | ||
| <tr class="border-b border-subtle last:border-0"> | ||
| <td class="px-4 py-2 font-mono text-primary">{prop.name}</td> | ||
| <td class="max-w-xs px-4 py-2 font-mono text-xs text-secondary"> | ||
| {formatType(prop.type)} | ||
| </td> | ||
| <td class="px-4 py-2 text-secondary">{prop.required ? "Yes" : "No"}</td> | ||
| <td class="px-4 py-2 text-secondary">{prop.description}</td> | ||
| </tr> | ||
| ))} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }) | ||
| } | ||
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| --- | ||
| import { COMPONENTS } from "~/lib/components-registry"; | ||
|
|
||
| const currentPath = Astro.url.pathname.replace(/\/$/, ""); | ||
| --- | ||
|
|
||
| <nav class="w-56 shrink-0"> | ||
| <p class="mb-3 text-xs font-medium tracking-wide text-tertiary uppercase">Components</p> | ||
| <ul class="flex flex-col gap-1"> | ||
| { | ||
| COMPONENTS.map((entry) => { | ||
| const href = `/components/${entry.slug}`; | ||
| const isActive = currentPath === href; | ||
| return ( | ||
| <li> | ||
| <a | ||
| href={href} | ||
| aria-current={isActive ? "page" : undefined} | ||
| class={`block rounded-md px-3 py-1.5 text-sm ${ | ||
| isActive | ||
| ? "bg-surface-2 text-primary" | ||
| : "text-secondary hover:bg-surface-1 hover:text-primary" | ||
| }`} | ||
| > | ||
| {entry.title} | ||
| </a> | ||
| </li> | ||
| ); | ||
| }) | ||
| } | ||
| </ul> | ||
| </nav> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { | ||
| Accordion, | ||
| AccordionHeader, | ||
| AccordionItem, | ||
| AccordionPanel, | ||
| AccordionTrigger, | ||
| } from "@makeplane/propel/components/accordion"; | ||
|
|
||
| const ITEMS = [ | ||
| { | ||
| value: "what", | ||
| label: "What is Plane?", | ||
| body: "Plane is an open-source project management tool for tracking issues, sprints, and product roadmaps.", | ||
| }, | ||
| { | ||
| value: "pricing", | ||
| label: "How does pricing work?", | ||
| body: "Plane is free to self-host. Managed plans add hosting, backups, and support.", | ||
| }, | ||
| ]; | ||
|
|
||
| export default function BasicDemo() { | ||
| return ( | ||
| <Accordion defaultValue={["what"]}> | ||
| {ITEMS.map((item) => ( | ||
| <AccordionItem key={item.value} value={item.value}> | ||
| <AccordionHeader> | ||
| <AccordionTrigger label={item.label} /> | ||
| </AccordionHeader> | ||
| <AccordionPanel>{item.body}</AccordionPanel> | ||
| </AccordionItem> | ||
| ))} | ||
| </Accordion> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import { Button } from "@makeplane/propel/components/button"; | ||
|
|
||
| export default function BasicDemo() { | ||
| return <Button label="Button" prominence="primary" tone="neutral" magnitude="md" sizing="hug" />; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { Button } from "@makeplane/propel/components/button"; | ||
| import { Plus } from "lucide-react"; | ||
|
|
||
| export default function WithIconDemo() { | ||
| return ( | ||
| <Button | ||
| label="New" | ||
| prominence="primary" | ||
| tone="neutral" | ||
| magnitude="md" | ||
| sizing="hug" | ||
| startIcon={<Plus />} | ||
| /> | ||
| ); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.