howl/src/avatar.tsx
2025-11-29 22:44:51 -08:00

128 lines
3.7 KiB
TypeScript

import { Section } from "./section"
import { H2, Text } from "./text"
import "hono/jsx"
import type { FC, JSX } from "hono/jsx"
import { VStack, HStack } from "./stack"
export type AvatarProps = {
src: string
alt?: string
size?: number
rounded?: boolean
style?: JSX.CSSProperties
}
export const Avatar: FC<AvatarProps> = (props) => {
const { src, size = 32, rounded, style, alt = "" } = props
const avatarStyle: JSX.CSSProperties = {
width: `${size}px`,
height: `${size}px`,
borderRadius: rounded ? "9999px" : undefined,
...style,
}
return <img src={src} alt={alt} style={avatarStyle} />
}
export const Test = () => {
const sampleImages = [
"https://picsum.photos/seed/3/200/200",
"https://picsum.photos/seed/2/200/200",
"https://picsum.photos/seed/8/200/200",
"https://picsum.photos/seed/9/200/200",
]
return (
<Section>
{/* API Usage Examples */}
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}>
<div>&lt;Avatar src="/user.jpg" /&gt;</div>
<div>&lt;Avatar src="/user.jpg" size=&#123;64&#125; /&gt;</div>
<div>&lt;Avatar src="/user.jpg" size=&#123;48&#125; rounded /&gt;</div>
<div>&lt;Avatar src="/user.jpg" style=&#123;&#123; border: "2px solid blue" &#125;&#125; /&gt;</div>
</VStack>
{/* Size variations */}
<VStack gap={4}>
<H2>Size Variations</H2>
<HStack gap={4}>
{[24, 32, 48, 64, 96].map((size) => (
<VStack key={size} h="center" gap={2}>
<Avatar src={sampleImages[0]!} size={size} alt="Sample" />
<Text>
{size}x{size}
</Text>
</VStack>
))}
</HStack>
</VStack>
{/* Rounded vs Square */}
<VStack gap={4}>
<H2>Rounded vs Square</H2>
<HStack gap={6}>
<VStack h="center" gap={2}>
<Avatar src={sampleImages[0]!} size={64} alt="Sample" />
<Text>Square</Text>
</VStack>
<VStack h="center" gap={2}>
<Avatar src={sampleImages[0]!} size={64} rounded alt="Sample" />
<Text>Rounded</Text>
</VStack>
</HStack>
</VStack>
{/* Different images */}
<VStack gap={4}>
<H2>Different Images</H2>
<HStack gap={4}>
{sampleImages.map((src, index) => (
<VStack key={src} h="center" gap={2}>
<Avatar src={src} size={64} rounded alt={`Sample ${index + 1}`} />
<Text>Image {index + 1}</Text>
</VStack>
))}
</HStack>
</VStack>
{/* Custom styles */}
<VStack gap={4}>
<H2>With Custom Styles</H2>
<HStack gap={6}>
<VStack h="center" gap={2}>
<Avatar
src={sampleImages[0]!}
size={64}
rounded
style={{ border: "4px solid #3b82f6" }}
alt="With border"
/>
<Text>With Border</Text>
</VStack>
<VStack h="center" gap={2}>
<Avatar
src={sampleImages[1]!}
size={64}
rounded
style={{ boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)" }}
alt="With shadow"
/>
<Text>With Shadow</Text>
</VStack>
<VStack h="center" gap={2}>
<Avatar
src={sampleImages[2]!}
size={64}
rounded
style={{ border: "4px solid #22c55e", boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)" }}
alt="Border + shadow"
/>
<Text>Border + Shadow</Text>
</VStack>
</HStack>
</VStack>
</Section>
)
}