Skip to content

Commit

Permalink
feat(docs):component & example source (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamdin authored Aug 31, 2024
1 parent 459bb9c commit d9b9f5a
Show file tree
Hide file tree
Showing 19 changed files with 304 additions and 554 deletions.
22 changes: 20 additions & 2 deletions apps/www/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,32 @@ import mdx from "@astrojs/mdx"
import react from "@astrojs/react"
import tailwind from "@astrojs/tailwind"
import vue from "@astrojs/vue"
import { transformerMetaHighlight } from "@shikijs/transformers"
import { defineConfig } from "astro/config"
import type { Element, Root } from "hast"
import Inspect from "vite-plugin-inspect"
import { rehypeCodeWrapper, shikiConfig } from "./src/lib/code"
import rehypeCodeWrapper from "./src/lib/rehype-code-wrapper"

// https://astro.build/config
export default defineConfig({
integrations: [
mdx({ shikiConfig, rehypePlugins: [rehypeCodeWrapper] }),
mdx({
shikiConfig: {
theme: "vesper",
transformers: [
{
root(root: Root) {
const pre = root.children?.[0] as Element
if (pre) pre.properties.source = this.source
},
},
transformerMetaHighlight({
className: "line--highlighted",
}),
],
},
rehypePlugins: [rehypeCodeWrapper],
}),
react(),
vue(),
tailwind(),
Expand Down
2 changes: 2 additions & 0 deletions apps/www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@fontsource-variable/inter": "^5.0.20",
"@nanostores/react": "^0.7.3",
"@nanostores/vue": "^0.10.0",
"@ui/lib": "workspace:*",
"@ui/react": "workspace:*",
"@ui/vue": "workspace:*",
"astro": "^4.14.6",
Expand All @@ -30,6 +31,7 @@
"react": "catalog:",
"react-dom": "catalog:",
"recharts": "^2.12.7",
"scule": "^1.3.0",
"sharp": "^0.32.6",
"tailwind-merge": "catalog:"
},
Expand Down
2 changes: 2 additions & 0 deletions apps/www/src/atoms/framework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ import { atom } from "nanostores"

export type Framework = "react" | "vue"

export const frameworks: Framework[] = ["react", "vue"]

export const $framework = atom<Framework>("react")
10 changes: 7 additions & 3 deletions apps/www/src/components/content/code-wrapper/code-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { cn } from "@/lib/utils"

interface Props {
collapsible?: boolean
copy?: boolean
children?: React.ReactNode
className: string | undefined
src: string
className?: string
src?: string
[key: string]: unknown
}

Expand All @@ -17,6 +18,7 @@ export default function CodeWrapper({
className,
src,
collapsible,
copy = true,
...props
}: Props) {
const [open, setOpen] = useState(false)
Expand Down Expand Up @@ -45,7 +47,9 @@ export default function CodeWrapper({
</Button>
</div>
) : null}
<CopyButton className="absolute top-4 right-4" value={src} />
{copy ? (
<CopyButton className="absolute top-4 right-4" value={src} />
) : null}
</div>
)
}
18 changes: 7 additions & 11 deletions apps/www/src/components/content/code-wrapper/index.astro
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
---
import { Code } from "astro/components"
import type { HTMLAttributes } from "astro/types"
import type { BuiltinLanguage } from "shiki"
import CodeWrapper from "./code-wrapper"
interface Props extends HTMLAttributes<"div"> {
lang?: "tsx" | "vue" | "ts" | "json"
src?: string
lang?: BuiltinLanguage
className?: string
collapsible?: boolean
src: string
copy?: boolean
}
const { src, lang, className, collapsible, ...props } = Astro.props
const { src, lang, className, ...props } = Astro.props
---

<CodeWrapper
client:visible
src={src}
collapsible={!!collapsible}
className={className}
{...props}
>
<Code lang={lang || "plaintext"} theme="vesper" code={src} />
<CodeWrapper client:visible src={src} className={className} {...props}>
<Code lang={lang || "plaintext"} theme="vesper" code={src || "Not found"} />
</CodeWrapper>
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useStore } from "@nanostores/react"
import { useEffect, useState } from "react"
import { pascalCase } from "scule"

import { $framework, type Framework } from "@/atoms/framework"
import { $framework, type Framework, frameworks } from "@/atoms/framework"
import {
Select,
SelectContent,
Expand All @@ -12,21 +13,10 @@ import {
SelectValueText,
} from "@ui/react/select"

const frameworks = [
{
value: "react",
label: "React",
},
{
value: "vue",
label: "Vue",
},
{
value: "solid",
label: "Solid (WIP)",
disabled: true,
},
]
const frameworksItems = frameworks.map((framework) => ({
value: framework,
label: pascalCase(framework),
}))

export function FrameworkSwitcher() {
const framework = useStore($framework)
Expand All @@ -45,7 +35,7 @@ export function FrameworkSwitcher() {
}}
className="w-[160px]"
positioning={{ sameWidth: true }}
items={frameworks}
items={frameworksItems}
>
<SelectControl>
<SelectTrigger className="h-7 text-xs">
Expand All @@ -55,13 +45,9 @@ export function FrameworkSwitcher() {
</SelectControl>
<SelectContent>
<SelectItemGroup>
{frameworks.map((framework) => (
<SelectItem
className="text-xs"
item={framework}
key={framework.value}
>
{framework.label}
{frameworksItems.map((item) => (
<SelectItem className="text-xs" item={item} key={item.value}>
{item.label}
</SelectItem>
))}
</SelectItemGroup>
Expand Down
136 changes: 46 additions & 90 deletions apps/www/src/components/content/component-preview/index.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
import fs from "node:fs/promises"
import { CopyButton } from "@/components/copy-button"
import { type ResolveOptions, resolvePath } from "mlly"
import { getExampleSource } from "@/lib/source"
import { frameworks } from "@/atoms/framework"
import CodeWrapper from "../code-wrapper/index.astro"
import { FrameworkSwitcher } from "./framework-switcher"
import NotFound from "./not-found.astro"
Expand All @@ -14,22 +15,11 @@ interface Props {
}
const { name } = Astro.props
const resolvePathAndReadFile = async (id: string, options: ResolveOptions) => {
try {
const filePath = await resolvePath(id, options)
return fs.readFile(filePath, "utf-8")
} catch (error) {
console.log("error", error)
return false
}
}
const source = await resolvePathAndReadFile(`@ui/react/examples/${name}`, {
conditions: ["source"],
})
const sourceVue = await resolvePathAndReadFile(`@ui/vue/examples/${name}`, {
conditions: ["source"],
})
const frameworkSources = await Promise.all(
frameworks.map(async (framework) => {
return await getExampleSource(framework, name)
})
)
---

<div class="group relative my-4 flex flex-col space-y-2">
Expand All @@ -38,84 +28,50 @@ const sourceVue = await resolvePathAndReadFile(`@ui/vue/examples/${name}`, {
<div class="relative rounded-md border">
<div class="flex items-center justify-between p-4">
<FrameworkSwitcher client:load />
<CopyButton
client:load
value={source || ""}
variant="outline"
className="h-7 w-7 text-foreground opacity-100 hover:bg-muted hover:text-foreground [&_svg]:h-3.5 [&_svg]:w-3.5"
data-framework="react"
/>
<CopyButton
client:load
value={sourceVue || ""}
variant="outline"
className="h-7 w-7 text-foreground opacity-100 hover:bg-muted hover:text-foreground [&_svg]:h-3.5 [&_svg]:w-3.5"
data-framework="vue"
hidden
/>
</div>
<div
class="preview flex min-h-[350px] w-full items-center justify-center p-10"
data-framework="react"
>
{
source ? (
<Preview client:visible name={name} />
) : (
<NotFound component={name} />
)
}
</div>
<div
class="preview flex min-h-[350px] w-full items-center justify-center p-10"
hidden
data-framework="vue"
>
{
sourceVue ? (
<PreviewVue client:visible name={name} />
) : (
<NotFound component={name} />
)
frameworks.map((framework, index) => (
<CopyButton
client:load
value={frameworkSources[index]?.source}
variant="outline"
className="h-7 w-7 text-foreground opacity-100 hover:bg-muted hover:text-foreground [&_svg]:h-3.5 [&_svg]:w-3.5"
data-framework={framework}
/>
))
}
</div>
{
frameworks.map((framework, index) => (
<div
class="preview flex min-h-[350px] w-full items-center justify-center p-10"
data-framework={framework}
hidden={framework !== "react"}
>
{frameworkSources[index] ? (
framework === "react" ? (
<Preview client:visible name={name} />
) : (
<PreviewVue client:visible name={name} />
)
) : (
<NotFound component={name} />
)}
</div>
))
}
</div>
</Fragment>
<Fragment slot="code">
<CodeWrapper data-framework="react" lang="tsx" src={source || ""} />
<CodeWrapper
data-framework="vue"
lang="vue"
src={sourceVue || ""}
hidden
/>
{
frameworks.map((framework, index) => (
<CodeWrapper
data-framework={framework}
lang={frameworkSources[index]?.lang}
src={frameworkSources[index]?.source}
hidden={framework !== "react"}
/>
))
}
</Fragment>
</Tabs>
</div>

<script>
import { $framework } from "@/atoms/framework";

let unsubscribe: () => void;

document.addEventListener("astro:page-load", () => {
if (typeof unsubscribe === "function") {
unsubscribe();
}

unsubscribe = $framework.subscribe((value) => {
const previewReact = document.querySelectorAll(
`[data-framework="react"]`
);
const previewVue = document.querySelectorAll(`[data-framework="vue"]`);
previewReact.forEach((el) => {
// @ts-ignore
el.hidden = value !== "react";
});
previewVue.forEach((el) => {
// @ts-ignore
el.hidden = value !== "vue";
});
});
});
</script>
34 changes: 26 additions & 8 deletions apps/www/src/components/content/component-source.astro
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
---
import fs from "node:fs"
import { resolvePath } from "mlly"
import { frameworks } from "@/atoms/framework"
import { getComponentSource } from "@/lib/source"
import CodeWrapper from "./code-wrapper/index.astro"
export interface Props {
component: string
}
const { component } = Astro.props
const filePath = await resolvePath(`@ui/react/${component}`, {
conditions: ["source"],
})
const source = fs.readFileSync(filePath, "utf-8")
const frameworkSources = await Promise.all(
frameworks.map((framework) => getComponentSource(framework, component))
)
---

<CodeWrapper lang="tsx" src={source} collapsible />
{
frameworks.map((framework, index) => (
<div data-framework={framework}>
{frameworkSources[index]?.length ? (
frameworkSources[index]?.map((src) => (
<div data-framework={framework}>
<p class="mb-2">{src.filename}</p>
<CodeWrapper
className="mt-0"
lang={src.lang}
src={src.source}
collapsible
/>
</div>
))
) : (
<CodeWrapper src={"Not Found"} />
)}
</div>
))
}
Loading

0 comments on commit d9b9f5a

Please sign in to comment.