230 lines
7.2 KiB
TypeScript
230 lines
7.2 KiB
TypeScript
import { Section } from "./section"
|
|
import { H2, H3, H4, H5, Text, SmallText } from "./text"
|
|
import "hono/jsx"
|
|
import type { FC, JSX } from "hono/jsx"
|
|
import { VStack, HStack } from "./stack"
|
|
import { Grid } from "./grid"
|
|
|
|
export type ImageProps = {
|
|
src: string
|
|
alt?: string
|
|
width?: number
|
|
height?: number
|
|
objectFit?: "cover" | "contain" | "fill" | "none" | "scale-down"
|
|
style?: JSX.CSSProperties
|
|
}
|
|
|
|
export const Image: FC<ImageProps> = ({ src, alt = "", width, height, objectFit, style }) => {
|
|
const imageStyle: JSX.CSSProperties = {
|
|
width: width ? `${width}px` : undefined,
|
|
height: height ? `${height}px` : undefined,
|
|
objectFit: objectFit,
|
|
...style,
|
|
}
|
|
|
|
return <img src={src} alt={alt} style={imageStyle} />
|
|
}
|
|
|
|
export const Test = () => {
|
|
const sampleImages = [
|
|
"https://picsum.photos/seed/1/400/600", // Portrait
|
|
"https://picsum.photos/seed/2/600/400", // Landscape
|
|
"https://picsum.photos/seed/3/300/300", // Square
|
|
"https://picsum.photos/seed/4/200/100", // Small image
|
|
]
|
|
|
|
return (
|
|
<Section>
|
|
{/* API Usage Examples */}
|
|
<VStack gap={2} style={{ backgroundColor: "#f9fafb", padding: "16px", borderRadius: "8px", fontFamily: "monospace", fontSize: "12px" }}>
|
|
<div><Image src="/photo.jpg" /></div>
|
|
<div><Image src="/photo.jpg" width={200} height={200} /></div>
|
|
<div><Image src="/photo.jpg" objectFit="cover" /></div>
|
|
<div><Image src="/photo.jpg" style={{ borderRadius: "8px" }} /></div>
|
|
</VStack>
|
|
|
|
<H2>Image Examples</H2>
|
|
|
|
{/* Size variations */}
|
|
<VStack gap={4}>
|
|
<H3>Size Variations</H3>
|
|
<HStack gap={4} wrap>
|
|
<VStack h="center" gap={2}>
|
|
<Image src={sampleImages[0]!} width={64} height={64} objectFit="cover" alt="64x64" />
|
|
<Text>64x64</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image src={sampleImages[0]!} width={96} height={96} objectFit="cover" alt="96x96" />
|
|
<Text>96x96</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image src={sampleImages[0]!} width={128} height={128} objectFit="cover" alt="128x128" />
|
|
<Text>128x128</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image src={sampleImages[0]!} width={192} height={128} objectFit="cover" alt="192x128" />
|
|
<Text>192x128</Text>
|
|
</VStack>
|
|
</HStack>
|
|
</VStack>
|
|
|
|
{/* Object fit variations */}
|
|
<VStack gap={4}>
|
|
<H3>Object Fit Variations</H3>
|
|
<Text>
|
|
Same image with different object-fit values
|
|
</Text>
|
|
<HStack gap={6} wrap>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="cover"
|
|
style={{ border: "1px solid black" }}
|
|
alt="Object cover"
|
|
/>
|
|
<Text>object-fit: cover</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="contain"
|
|
style={{ border: "1px solid black", backgroundColor: "#f3f4f6" }}
|
|
alt="Object contain"
|
|
/>
|
|
<Text>object-fit: contain</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="fill"
|
|
style={{ border: "1px solid black" }}
|
|
alt="Object fill"
|
|
/>
|
|
<Text>object-fit: fill</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="scale-down"
|
|
style={{ border: "1px solid black", backgroundColor: "#f3f4f6" }}
|
|
alt="Object scale-down"
|
|
/>
|
|
<Text>object-fit: scale-down</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="none"
|
|
style={{ border: "1px solid black", backgroundColor: "#f3f4f6" }}
|
|
alt="Object none"
|
|
/>
|
|
<Text>object-fit: none</Text>
|
|
</VStack>
|
|
</HStack>
|
|
</VStack>
|
|
|
|
{/* Styling examples */}
|
|
<VStack gap={4}>
|
|
<H3>Styling Examples</H3>
|
|
<HStack gap={6} wrap>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="cover"
|
|
style={{ borderRadius: "8px", border: "4px solid #3b82f6" }}
|
|
alt="Rounded with border"
|
|
/>
|
|
<Text>Rounded + Border</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[1]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="cover"
|
|
style={{ boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)" }}
|
|
alt="With shadow"
|
|
/>
|
|
<Text>With Shadow</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[2]!}
|
|
width={128}
|
|
height={128}
|
|
objectFit="cover"
|
|
style={{
|
|
borderRadius: "9999px",
|
|
border: "4px solid #22c55e",
|
|
boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)",
|
|
}}
|
|
alt="Circular with effects"
|
|
/>
|
|
<Text>Circular + Effects</Text>
|
|
</VStack>
|
|
</HStack>
|
|
</VStack>
|
|
|
|
{/* Common use cases */}
|
|
<VStack gap={6}>
|
|
<H3>Common Use Cases</H3>
|
|
|
|
{/* Avatar */}
|
|
<VStack gap={2}>
|
|
<H4>Avatar</H4>
|
|
<Image
|
|
src={sampleImages[0]!}
|
|
width={48}
|
|
height={48}
|
|
objectFit="cover"
|
|
style={{ borderRadius: "9999px" }}
|
|
alt="Avatar"
|
|
/>
|
|
</VStack>
|
|
|
|
{/* Card image */}
|
|
<VStack gap={2} style={{ maxWidth: "384px" }}>
|
|
<H4>Card Image</H4>
|
|
<VStack gap={0} style={{ border: "1px solid #d1d5db", borderRadius: "8px", overflow: "hidden" }}>
|
|
<Image src={sampleImages[1]!} width={384} height={192} objectFit="cover" alt="Card image" />
|
|
<VStack gap={1} style={{ padding: "16px" }}>
|
|
<H5>Card Title</H5>
|
|
<Text>Card description goes here</Text>
|
|
</VStack>
|
|
</VStack>
|
|
</VStack>
|
|
|
|
{/* Gallery grid */}
|
|
<VStack gap={2}>
|
|
<H4>Gallery Grid</H4>
|
|
<Grid cols={3} gap={2}>
|
|
{sampleImages.map((src, i) => (
|
|
<Image
|
|
key={i}
|
|
src={src}
|
|
width={120}
|
|
height={120}
|
|
objectFit="cover"
|
|
style={{ borderRadius: "4px" }}
|
|
alt={`Gallery ${i}`}
|
|
/>
|
|
))}
|
|
</Grid>
|
|
</VStack>
|
|
</VStack>
|
|
</Section>
|
|
)
|
|
}
|