forked from defunkt/howl
/ |/ \ / \ / \ / | $$$$$$$$//$$$$$$ |$$$$$$$ |/$$$$$$ |$$$$$$$$/ $$ |__ $$ | $$ |$$ |__$$ |$$ | _$$/ $$ |__ $$ | $$ | $$ |$$ $$< $$ |/ |$$ | $$$$$/ $$ | $$ |$$$$$$$ |$$ |$$$$ |$$$$$/ $$ | $$ \__$$ |$$ | $$ |$$ \__$$ |$$ |_____ $$ | $$ $$/ $$ | $$ |$$ $$/ $$ | $$/ $$$$$$/ $$/ $$/ $$$$$$/ $$$$$$$$/
197 lines
6.3 KiB
TypeScript
197 lines
6.3 KiB
TypeScript
import { define } from 'forge'
|
|
import { Section } from './section'
|
|
import { H2, H3, H4, H5, Text } from './text'
|
|
import { VStack, HStack } from './stack'
|
|
import { Grid } from './grid'
|
|
|
|
export const Image = define('Image', {
|
|
base: 'img',
|
|
|
|
variants: {
|
|
objectFit: {
|
|
cover: { objectFit: 'cover' },
|
|
contain: { objectFit: 'contain' },
|
|
fill: { objectFit: 'fill' },
|
|
none: { objectFit: 'none' },
|
|
'scale-down': { objectFit: 'scale-down' },
|
|
},
|
|
},
|
|
})
|
|
|
|
export type ImageProps = Parameters<typeof Image>[0]
|
|
|
|
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>
|
|
<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]} objectFit="cover" style={{ width: 64, height: 64 }} alt="64x64" />
|
|
<Text>64x64</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image src={sampleImages[0]} objectFit="cover" style={{ width: 96, height: 96 }} alt="96x96" />
|
|
<Text>96x96</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image src={sampleImages[0]} objectFit="cover" style={{ width: 128, height: 128 }} alt="128x128" />
|
|
<Text>128x128</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image src={sampleImages[0]} objectFit="cover" style={{ width: 192, height: 128 }} 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]}
|
|
objectFit="cover"
|
|
style={{ width: 128, height: 128, border: '1px solid black' }}
|
|
alt="Object cover"
|
|
/>
|
|
<Text>object-fit: cover</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]}
|
|
objectFit="contain"
|
|
style={{ width: 128, height: 128, border: '1px solid black', backgroundColor: '#f3f4f6' }}
|
|
alt="Object contain"
|
|
/>
|
|
<Text>object-fit: contain</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]}
|
|
objectFit="fill"
|
|
style={{ width: 128, height: 128, border: '1px solid black' }}
|
|
alt="Object fill"
|
|
/>
|
|
<Text>object-fit: fill</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[0]}
|
|
objectFit="scale-down"
|
|
style={{ width: 128, height: 128, 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]}
|
|
objectFit="none"
|
|
style={{ width: 128, height: 128, 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]}
|
|
objectFit="cover"
|
|
style={{ width: 128, height: 128, borderRadius: '8px', border: '4px solid #3b82f6' }}
|
|
alt="Rounded with border"
|
|
/>
|
|
<Text>Rounded + Border</Text>
|
|
</VStack>
|
|
<VStack h="center" gap={2}>
|
|
<Image
|
|
src={sampleImages[1]}
|
|
objectFit="cover"
|
|
style={{ width: 128, height: 128, 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]}
|
|
objectFit="cover"
|
|
style={{
|
|
width: 128,
|
|
height: 128,
|
|
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]}
|
|
objectFit="cover"
|
|
style={{ width: 48, height: 48, 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]} objectFit="cover" style={{ width: 384, height: 192 }} 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}
|
|
objectFit="cover"
|
|
style={{ width: 120, height: 120, borderRadius: '4px' }}
|
|
alt={`Gallery ${i}`}
|
|
/>
|
|
))}
|
|
</Grid>
|
|
</VStack>
|
|
</VStack>
|
|
</Section>
|
|
)
|
|
}
|