963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
2.5 KiB
2.5 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Use Galeria for Image Galleries and Lightbox | MEDIUM | native shared element transitions, pinch-to-zoom, pan-to-close | images, gallery, lightbox, expo-image, ui |
Use Galeria for Image Galleries and Lightbox
For image galleries with lightbox (tap to fullscreen), use @nandorojo/galeria.
It provides native shared element transitions with pinch-to-zoom, double-tap
zoom, and pan-to-close. Works with any image component including expo-image.
Incorrect (custom modal implementation):
function ImageGallery({ urls }: { urls: string[] }) {
const [selected, setSelected] = useState<string | null>(null);
return (
<>
{urls.map((url) => (
<Pressable key={url} onPress={() => setSelected(url)}>
<Image source={{ uri: url }} style={styles.thumbnail} />
</Pressable>
))}
<Modal visible={!!selected} onRequestClose={() => setSelected(null)}>
<Image source={{ uri: selected! }} style={styles.fullscreen} />
</Modal>
</>
);
}
Correct (Galeria with expo-image):
import { Galeria } from '@nandorojo/galeria';
import { Image } from 'expo-image';
function ImageGallery({ urls }: { urls: string[] }) {
return (
<Galeria urls={urls}>
{urls.map((url, index) => (
<Galeria.Image index={index} key={url}>
<Image source={{ uri: url }} style={styles.thumbnail} />
</Galeria.Image>
))}
</Galeria>
);
}
Single image:
import { Galeria } from '@nandorojo/galeria';
import { Image } from 'expo-image';
function Avatar({ url }: { url: string }) {
return (
<Galeria urls={[url]}>
<Galeria.Image>
<Image source={{ uri: url }} style={styles.avatar} />
</Galeria.Image>
</Galeria>
);
}
With low-res thumbnails and high-res fullscreen:
<Galeria urls={highResUrls}>
{lowResUrls.map((url, index) => (
<Galeria.Image index={index} key={url}>
<Image source={{ uri: url }} style={styles.thumbnail} />
</Galeria.Image>
))}
</Galeria>
With FlashList:
<Galeria urls={urls}>
<FlashList
data={urls}
renderItem={({ item, index }) => (
<Galeria.Image index={index}>
<Image source={{ uri: item }} style={styles.thumbnail} />
</Galeria.Image>
)}
numColumns={3}
estimatedItemSize={100}
/>
</Galeria>
Works with expo-image, SolitoImage, react-native Image, or any image
component.
Reference: Galeria