code examples

This commit is contained in:
Chris Wanstrath 2025-11-29 22:58:09 -08:00
parent 438aa3f5b4
commit 7db4fe00fd
16 changed files with 349 additions and 77 deletions

View File

@ -3,6 +3,7 @@ import { H2, Text } from "./text"
import "hono/jsx" import "hono/jsx"
import type { FC, JSX } from "hono/jsx" import type { FC, JSX } from "hono/jsx"
import { VStack, HStack } from "./stack" import { VStack, HStack } from "./stack"
import { CodeExamples } from "./code"
export type AvatarProps = { export type AvatarProps = {
src: string src: string
@ -36,12 +37,14 @@ export const Test = () => {
return ( return (
<Section> <Section>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Avatar src="/user.jpg" /&gt;</div> examples={[
<div>&lt;Avatar src="/user.jpg" size=&#123;64&#125; /&gt;</div> '<Avatar src="/user.jpg" />',
<div>&lt;Avatar src="/user.jpg" size=&#123;48&#125; rounded /&gt;</div> '<Avatar src="/user.jpg" size={64} />',
<div>&lt;Avatar src="/user.jpg" style=&#123;&#123; border: "2px solid blue" &#125;&#125; /&gt;</div> '<Avatar src="/user.jpg" size={48} rounded />',
</VStack> '<Avatar src="/user.jpg" style={{ border: "2px solid blue" }} />',
]}
/>
{/* Size variations */} {/* Size variations */}
<VStack gap={4}> <VStack gap={4}>

View File

@ -1,5 +1,6 @@
import "hono/jsx" import "hono/jsx"
import type { FC, PropsWithChildren, JSX } from "hono/jsx" import type { FC, PropsWithChildren, JSX } from "hono/jsx"
import { CodeExamples } from "./code"
type BoxProps = PropsWithChildren & { type BoxProps = PropsWithChildren & {
bg?: string bg?: string
@ -48,12 +49,14 @@ export const Test = () => {
return ( return (
<div style={{ display: "flex", flexDirection: "column", gap: "32px", padding: "24px" }}> <div style={{ display: "flex", flexDirection: "column", gap: "32px", padding: "24px" }}>
{/* API Usage Examples */} {/* API Usage Examples */}
<div style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px", display: "flex", flexDirection: "column", gap: "8px" }}> <CodeExamples
<div>&lt;Box&gt;Content&lt;/Box&gt;</div> examples={[
<div>&lt;Box bg="#3b82f6" p=&#123;16&#125;&gt;Content&lt;/Box&gt;</div> '<Box>Content</Box>',
<div>&lt;RedBox&gt;Content&lt;/RedBox&gt;</div> '<Box bg="#3b82f6" p={16}>Content</Box>',
<div>&lt;GrayBox&gt;Content&lt;/GrayBox&gt;</div> '<RedBox>Content</RedBox>',
</div> '<GrayBox>Content</GrayBox>',
]}
/>
<div> <div>
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Box Component</h2> <h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Box Component</h2>

View File

@ -3,6 +3,7 @@ import type { JSX, FC } from "hono/jsx"
import { VStack, HStack } from "./stack" import { VStack, HStack } from "./stack"
import { Section } from "./section" import { Section } from "./section"
import { H2 } from "./text" import { H2 } from "./text"
import { CodeExamples } from "./code"
export type ButtonProps = JSX.IntrinsicElements["button"] & { export type ButtonProps = JSX.IntrinsicElements["button"] & {
variant?: "primary" | "secondary" | "outline" | "ghost" | "destructive" variant?: "primary" | "secondary" | "outline" | "ghost" | "destructive"
@ -80,12 +81,14 @@ export const Test = () => {
return ( return (
<Section> <Section>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Button&gt;Click Me&lt;/Button&gt;</div> examples={[
<div>&lt;Button variant="secondary"&gt;Secondary&lt;/Button&gt;</div> '<Button>Click Me</Button>',
<div>&lt;Button variant="outline" size="lg"&gt;Large&lt;/Button&gt;</div> '<Button variant="secondary">Secondary</Button>',
<div>&lt;Button onClick=&#123;handleClick&#125;&gt;Action&lt;/Button&gt;</div> '<Button variant="outline" size="lg">Large</Button>',
</VStack> '<Button onClick={handleClick}>Action</Button>',
]}
/>
{/* Variants */} {/* Variants */}
<VStack gap={4}> <VStack gap={4}>

226
src/code.tsx Normal file
View File

@ -0,0 +1,226 @@
import "hono/jsx"
import type { FC } from "hono/jsx"
import { VStack } from "./stack"
type CodeProps = {
children: string
}
// Color scheme
const colors = {
tag: "#0ea5e9", // cyan-500
attr: "#8b5cf6", // violet-500
string: "#10b981", // emerald-500
number: "#f59e0b", // amber-500
brace: "#ef4444", // red-500
text: "#374151", // gray-700
}
// Lightweight JSX syntax highlighter
export const Code: FC<CodeProps> = ({ children }) => {
const tokens = tokenizeJSX(children)
return (
<div
style={{
fontFamily: "monospace",
fontSize: "13px",
lineHeight: "1.5",
}}
>
{tokens.map((token, i) => {
if (token.type === "tag") {
return (
<span key={i} style={{ color: colors.tag, fontWeight: "600" }}>
{token.value}
</span>
)
}
if (token.type === "attr") {
return (
<span key={i} style={{ color: colors.attr }}>
{token.value}
</span>
)
}
if (token.type === "string") {
return (
<span key={i} style={{ color: colors.string }}>
{token.value}
</span>
)
}
if (token.type === "number") {
return (
<span key={i} style={{ color: colors.number }}>
{token.value}
</span>
)
}
if (token.type === "brace") {
return (
<span key={i} style={{ color: colors.brace, fontWeight: "600" }}>
{token.value}
</span>
)
}
return <span key={i}>{token.value}</span>
})}
</div>
)
}
type CodeExamplesProps = {
examples: string[]
}
// Container for multiple code examples
export const CodeExamples: FC<CodeExamplesProps> = ({ examples }) => {
return (
<VStack
gap={2}
style={{
backgroundColor: "#f9fafb",
padding: "16px",
borderRadius: "8px",
border: "1px solid #e5e7eb",
}}
>
{examples.map((example, i) => (
<Code key={i}>{example}</Code>
))}
</VStack>
)
}
type Token = {
type: "tag" | "attr" | "string" | "number" | "brace" | "text"
value: string
}
function tokenizeJSX(code: string): Token[] {
const tokens: Token[] = []
let i = 0
while (i < code.length) {
// Match opening/closing tags: < or </
if (code[i] === "<") {
const tagStart = i
i++
// Check for closing tag
if (code[i] === "/") {
tokens.push({ type: "tag", value: "</" })
i++
} else {
tokens.push({ type: "tag", value: "<" })
}
// Get tag name
let tagName = ""
while (i < code.length && /[A-Za-z0-9.]/.test(code[i]!)) {
tagName += code[i]
i++
}
if (tagName) {
tokens.push({ type: "tag", value: tagName })
}
// Parse attributes inside the tag
while (i < code.length && code[i] !== ">") {
// Skip whitespace
if (/\s/.test(code[i]!)) {
tokens.push({ type: "text", value: code[i]! })
i++
continue
}
// Check for self-closing /
if (code[i] === "/" && code[i + 1] === ">") {
tokens.push({ type: "tag", value: " />" })
i += 2
break
}
// Parse attribute name
let attrName = ""
while (i < code.length && /[a-zA-Z0-9-]/.test(code[i]!)) {
attrName += code[i]
i++
}
if (attrName) {
tokens.push({ type: "attr", value: attrName })
}
// Check for =
if (code[i] === "=") {
tokens.push({ type: "text", value: "=" })
i++
// Parse attribute value
if (code[i] === '"') {
// String value
let str = '"'
i++
while (i < code.length && code[i] !== '"') {
str += code[i]
i++
}
if (code[i] === '"') {
str += '"'
i++
}
tokens.push({ type: "string", value: str })
} else if (code[i] === "{") {
// Brace value
tokens.push({ type: "brace", value: "{" })
i++
// Get content inside braces
let content = ""
let depth = 1
while (i < code.length && depth > 0) {
if (code[i] === "{") depth++
if (code[i] === "}") {
depth--
if (depth === 0) break
}
content += code[i]
i++
}
// Check if content is a number
if (/^\d+$/.test(content)) {
tokens.push({ type: "number", value: content })
} else {
tokens.push({ type: "text", value: content })
}
if (code[i] === "}") {
tokens.push({ type: "brace", value: "}" })
i++
}
}
}
}
// Closing >
if (code[i] === ">") {
tokens.push({ type: "tag", value: ">" })
i++
}
} else {
// Regular text
let text = ""
while (i < code.length && code[i] !== "<") {
text += code[i]
i++
}
if (text) {
tokens.push({ type: "text", value: text })
}
}
}
return tokens
}

View File

@ -3,6 +3,7 @@ import { H2 } from "./text"
import "hono/jsx" import "hono/jsx"
import type { FC, PropsWithChildren, JSX } from "hono/jsx" import type { FC, PropsWithChildren, JSX } from "hono/jsx"
import { VStack } from "./stack" import { VStack } from "./stack"
import { CodeExamples } from "./code"
type DividerProps = PropsWithChildren & { type DividerProps = PropsWithChildren & {
style?: JSX.CSSProperties style?: JSX.CSSProperties
@ -45,11 +46,13 @@ export const Test = () => {
return ( return (
<Section gap={4} maxWidth="448px" style={{ padding: "16px" }}> <Section gap={4} maxWidth="448px" style={{ padding: "16px" }}>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Divider /&gt;</div> examples={[
<div>&lt;Divider&gt;OR&lt;/Divider&gt;</div> '<Divider />',
<div>&lt;Divider style=&#123;&#123; margin: "24px 0" &#125;&#125; /&gt;</div> '<Divider>OR</Divider>',
</VStack> '<Divider style={{ margin: "24px 0" }} />',
]}
/>
<H2>Divider Examples</H2> <H2>Divider Examples</H2>

View File

@ -5,6 +5,7 @@ import { VStack } from "./stack"
import { Button } from "./button" import { Button } from "./button"
import { Section } from "./section" import { Section } from "./section"
import { H2, H3 } from "./text" import { H2, H3 } from "./text"
import { CodeExamples } from "./code"
type GridProps = PropsWithChildren & { type GridProps = PropsWithChildren & {
cols?: GridCols cols?: GridCols
@ -73,12 +74,14 @@ export const Test = () => {
return ( return (
<Section gap={4} style={{ padding: "16px" }}> <Section gap={4} style={{ padding: "16px" }}>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Grid cols=&#123;3&#125;&gt;...&lt;/Grid&gt;</div> examples={[
<div>&lt;Grid cols=&#123;4&#125; gap=&#123;6&#125;&gt;...&lt;/Grid&gt;</div> '<Grid cols={3}>...</Grid>',
<div>&lt;Grid cols=&#123;&#123; sm: 1, md: 2, lg: 3 &#125;&#125;&gt;...&lt;/Grid&gt;</div> '<Grid cols={4} gap={6}>...</Grid>',
<div>&lt;Grid cols=&#123;2&#125; v="center" h="center"&gt;...&lt;/Grid&gt;</div> '<Grid cols={{ sm: 1, md: 2, lg: 3 }}>...</Grid>',
</VStack> '<Grid cols={2} v="center" h="center">...</Grid>',
]}
/>
<VStack gap={6}> <VStack gap={6}>
<H2>Grid Examples</H2> <H2>Grid Examples</H2>

View File

@ -5,6 +5,7 @@ import { Grid } from "./grid"
import { VStack } from "./stack" import { VStack } from "./stack"
import { Section } from "./section" import { Section } from "./section"
import { H2, Text } from "./text" import { H2, Text } from "./text"
import { CodeExamples } from "./code"
export type IconName = keyof typeof icons export type IconName = keyof typeof icons
@ -73,12 +74,14 @@ export const Test = () => {
return ( return (
<Section> <Section>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Icon name="Heart" /&gt;</div> examples={[
<div>&lt;Icon name="Star" size=&#123;8&#125; /&gt;</div> '<Icon name="Heart" />',
<div>&lt;Icon name="Home" style=&#123;&#123; color: "#3b82f6" &#125;&#125; /&gt;</div> '<Icon name="Star" size={8} />',
<div>&lt;IconLink name="ExternalLink" href="/link" /&gt;</div> '<Icon name="Home" style={{ color: "#3b82f6" }} />',
</VStack> '<IconLink name="ExternalLink" href="/link" />',
]}
/>
{/* === ICON TESTS === */} {/* === ICON TESTS === */}

View File

@ -4,6 +4,7 @@ import "hono/jsx"
import type { FC, JSX } from "hono/jsx" import type { FC, JSX } from "hono/jsx"
import { VStack, HStack } from "./stack" import { VStack, HStack } from "./stack"
import { Grid } from "./grid" import { Grid } from "./grid"
import { CodeExamples } from "./code"
export type ImageProps = { export type ImageProps = {
src: string src: string
@ -36,12 +37,14 @@ export const Test = () => {
return ( return (
<Section> <Section>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Image src="/photo.jpg" /&gt;</div> examples={[
<div>&lt;Image src="/photo.jpg" width=&#123;200&#125; height=&#123;200&#125; /&gt;</div> '<Image src="/photo.jpg" />',
<div>&lt;Image src="/photo.jpg" objectFit="cover" /&gt;</div> '<Image src="/photo.jpg" width={200} height={200} />',
<div>&lt;Image src="/photo.jpg" style=&#123;&#123; borderRadius: "8px" &#125;&#125; /&gt;</div> '<Image src="/photo.jpg" objectFit="cover" />',
</VStack> '<Image src="/photo.jpg" style={{ borderRadius: "8px" }} />',
]}
/>
<H2>Image Examples</H2> <H2>Image Examples</H2>

View File

@ -3,6 +3,7 @@ import { H2, H3, H4, H5, Text, SmallText } from "./text"
import "hono/jsx" import "hono/jsx"
import type { JSX, FC } from "hono/jsx" import type { JSX, FC } from "hono/jsx"
import { VStack, HStack } from "./stack" import { VStack, HStack } from "./stack"
import { CodeExamples } from "./code"
export type InputProps = JSX.IntrinsicElements["input"] & { export type InputProps = JSX.IntrinsicElements["input"] & {
labelPosition?: "above" | "left" | "right" labelPosition?: "above" | "left" | "right"
@ -73,12 +74,14 @@ export const Test = () => {
return ( return (
<Section maxWidth="448px"> <Section maxWidth="448px">
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Input placeholder="Enter name" /&gt;</div> examples={[
<div>&lt;Input type="email" placeholder="Email" /&gt;</div> '<Input placeholder="Enter name" />',
<div>&lt;Input&gt;Label&lt;/Input&gt;</div> '<Input type="email" placeholder="Email" />',
<div>&lt;Input labelPosition="left"&gt;Name&lt;/Input&gt;</div> '<Input>Label</Input>',
</VStack> '<Input labelPosition="left">Name</Input>',
]}
/>
{/* Basic inputs */} {/* Basic inputs */}
<VStack gap={4}> <VStack gap={4}>

View File

@ -7,6 +7,7 @@ import { Image } from "./image"
import type { ImageProps } from "./image" import type { ImageProps } from "./image"
import { VStack, HStack } from "./stack" import { VStack, HStack } from "./stack"
import { Grid } from "./grid" import { Grid } from "./grid"
import { CodeExamples } from "./code"
export const Placeholder = { export const Placeholder = {
Avatar(props: PlaceholderAvatarProps) { Avatar(props: PlaceholderAvatarProps) {
@ -38,12 +39,14 @@ export const Test = () => {
return ( return (
<Section> <Section>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Placeholder.Avatar /&gt;</div> examples={[
<div>&lt;Placeholder.Avatar type="avataaars" size=&#123;64&#125; /&gt;</div> '<Placeholder.Avatar />',
<div>&lt;Placeholder.Image width=&#123;200&#125; height=&#123;200&#125; /&gt;</div> '<Placeholder.Avatar type="avataaars" size={64} />',
<div>&lt;Placeholder.Image seed=&#123;42&#125; /&gt;</div> '<Placeholder.Image width={200} height={200} />',
</VStack> '<Placeholder.Image seed={42} />',
]}
/>
{/* === AVATAR TESTS === */} {/* === AVATAR TESTS === */}

View File

@ -2,6 +2,7 @@ import "hono/jsx"
import type { FC, PropsWithChildren, JSX } from "hono/jsx" import type { FC, PropsWithChildren, JSX } from "hono/jsx"
import { VStack } from "./stack" import { VStack } from "./stack"
import type { TailwindSize } from "./types" import type { TailwindSize } from "./types"
import { CodeExamples } from "./code"
type SectionProps = PropsWithChildren & { type SectionProps = PropsWithChildren & {
gap?: TailwindSize gap?: TailwindSize
@ -21,11 +22,15 @@ export const Test = () => {
return ( return (
<div> <div>
{/* API Usage Examples */} {/* API Usage Examples */}
<div style={{ backgroundColor: "#f9fafb", padding: "16px", margin: "24px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px", display: "flex", flexDirection: "column", gap: "8px" }}> <div style={{ margin: "24px" }}>
<div>&lt;Section&gt;...&lt;/Section&gt;</div> <CodeExamples
<div>&lt;Section gap=&#123;4&#125;&gt;...&lt;/Section&gt;</div> examples={[
<div>&lt;Section maxWidth="600px"&gt;...&lt;/Section&gt;</div> '<Section>...</Section>',
<div>&lt;Section style=&#123;&#123; backgroundColor: "#f3f4f6" &#125;&#125;&gt;...&lt;/Section&gt;</div> '<Section gap={4}>...</Section>',
'<Section maxWidth="600px">...</Section>',
'<Section style={{ backgroundColor: "#f3f4f6" }}>...</Section>',
]}
/>
</div> </div>
<Section> <Section>

View File

@ -3,6 +3,7 @@ import { H2, H3, H4, H5, Text, SmallText } from "./text"
import "hono/jsx" import "hono/jsx"
import type { JSX, FC } from "hono/jsx" import type { JSX, FC } from "hono/jsx"
import { VStack, HStack } from "./stack" import { VStack, HStack } from "./stack"
import { CodeExamples } from "./code"
export type SelectOption = { export type SelectOption = {
value: string value: string
@ -164,12 +165,14 @@ export const Test = () => {
return ( return (
<Section maxWidth="448px"> <Section maxWidth="448px">
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;Select options=&#123;options&#125; /&gt;</div> examples={[
<div>&lt;Select options=&#123;options&#125; placeholder="Choose" /&gt;</div> '<Select options={options} />',
<div>&lt;Select options=&#123;options&#125;&gt;Label&lt;/Select&gt;</div> '<Select options={options} placeholder="Choose" />',
<div>&lt;Select options=&#123;options&#125; labelPosition="left"&gt;Label&lt;/Select&gt;</div> '<Select options={options}>Label</Select>',
</VStack> '<Select options={options} labelPosition="left">Label</Select>',
]}
/>
{/* Basic selects */} {/* Basic selects */}
<VStack gap={4}> <VStack gap={4}>

View File

@ -5,6 +5,7 @@ import { Grid } from "./grid"
import { Section } from "./section" import { Section } from "./section"
import { H2 } from "./text" import { H2 } from "./text"
import { RedBox, GreenBox, BlueBox } from "./box" import { RedBox, GreenBox, BlueBox } from "./box"
import { CodeExamples } from "./code"
export const VStack: FC<VStackProps> = (props) => { export const VStack: FC<VStackProps> = (props) => {
return ( return (
@ -69,12 +70,14 @@ export const Test = () => {
return ( return (
<Section gap={8} style={{ padding: "16px" }}> <Section gap={8} style={{ padding: "16px" }}>
{/* API Usage Examples */} {/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}> <CodeExamples
<div>&lt;VStack&gt;...&lt;/VStack&gt;</div> examples={[
<div>&lt;VStack gap=&#123;4&#125; v="center"&gt;...&lt;/VStack&gt;</div> '<VStack>...</VStack>',
<div>&lt;HStack&gt;...&lt;/HStack&gt;</div> '<VStack gap={4} v="center">...</VStack>',
<div>&lt;HStack gap=&#123;6&#125; h="between" v="center"&gt;...&lt;/HStack&gt;</div> '<HStack>...</HStack>',
</VStack> '<HStack gap={6} h="between" v="center">...</HStack>',
]}
/>
{/* HStack layout matrix */} {/* HStack layout matrix */}
<VStack gap={2}> <VStack gap={2}>

View File

@ -1,5 +1,6 @@
import "hono/jsx" import "hono/jsx"
import type { FC, PropsWithChildren, JSX } from "hono/jsx" import type { FC, PropsWithChildren, JSX } from "hono/jsx"
import { CodeExamples } from "./code"
type TextProps = PropsWithChildren & { type TextProps = PropsWithChildren & {
style?: JSX.CSSProperties style?: JSX.CSSProperties
@ -37,12 +38,14 @@ export const Test = () => {
return ( return (
<div style={{ padding: "24px", display: "flex", flexDirection: "column", gap: "32px" }}> <div style={{ padding: "24px", display: "flex", flexDirection: "column", gap: "32px" }}>
{/* API Usage Examples */} {/* API Usage Examples */}
<div style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px", display: "flex", flexDirection: "column", gap: "8px" }}> <CodeExamples
<div>&lt;H1&gt;Heading 1&lt;/H1&gt;</div> examples={[
<div>&lt;H2&gt;Heading 2&lt;/H2&gt;</div> '<H1>Heading 1</H1>',
<div>&lt;Text&gt;Regular text&lt;/Text&gt;</div> '<H2>Heading 2</H2>',
<div>&lt;SmallText&gt;Small text&lt;/SmallText&gt;</div> '<Text>Regular text</Text>',
</div> '<SmallText>Small text</SmallText>',
]}
/>
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}> <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
<H1>Heading 1 (24px, bold)</H1> <H1>Heading 1 (24px, bold)</H1>

View File

@ -1,6 +1,7 @@
import { Hono } from 'hono' import { Hono } from 'hono'
import { readdirSync } from 'fs' import { readdirSync } from 'fs'
import { join } from 'path' import { join } from 'path'
import { capitalize } from './utils'
const port = process.env.PORT ?? '3100' const port = process.env.PORT ?? '3100'
const app = new Hono() const app = new Hono()
@ -14,7 +15,7 @@ app.get('/:file', async c => {
return c.text('404 Not Found', 404) return c.text('404 Not Found', 404)
const page = await import(path + `?t=${Date.now()}`) const page = await import(path + `?t=${Date.now()}`)
return c.html(<><h1>{file}</h1><page.Test req={c.req} /></>) return c.html(<><h1>&lt;{capitalize(file)} /&gt;</h1><page.Test req={c.req} /></>)
}) })
app.get('/', c => { app.get('/', c => {

4
test/utils.ts Normal file
View File

@ -0,0 +1,4 @@
// capitalize a word. that's it.
export function capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1)
}