mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
Both old names are owned by a different npm account (artemis-prime), so publishing them returns 403 — which is how this surfaced: the 8.0.0 run shipped @hanzogui/logo and @hanzogui/demos depending on [email protected], a version that cannot be published and therefore does not exist. Those two were uninstallable. @hanzo/gui and @hanzogui/* are ours, so the framework now carries the name it is imported by everywhere downstream, and the loader moves under the scope we control. The rewrite is limited to package references. `DEBUG?.startsWith('hanzogui')` is a log-namespace filter and join(dir, 'hanzogui') is a path — rewriting either would change behaviour, so both are untouched. Co-authored-by: Hanzo Dev <[email protected]>
324 lines
7.7 KiB
Plaintext
324 lines
7.7 KiB
Plaintext
---
|
|
title: Image
|
|
description: A pure, lightweight Image component with Gui style props
|
|
name: image
|
|
component: Image
|
|
package: image
|
|
demoName: Image
|
|
---
|
|
|
|
<HeroContainer noPad>
|
|
<ImageDemo />
|
|
</HeroContainer>
|
|
|
|
```tsx hero template=Image
|
|
|
|
```
|
|
|
|
<Highlights
|
|
features={[
|
|
'Supports SSR.',
|
|
'Works on native and web.',
|
|
'Accepts Gui style props.',
|
|
'Pluggable architecture with createImage for expo-image and more.',
|
|
]}
|
|
/>
|
|
|
|
## Installation
|
|
|
|
Image is already installed in `hanzogui`, or you can install it independently:
|
|
|
|
```bash
|
|
npm install @hanzogui/image
|
|
```
|
|
|
|
## Usage
|
|
|
|
Use the `src` prop for the image URL:
|
|
|
|
```tsx
|
|
import { Image } from '@hanzo/gui'
|
|
|
|
export default () => (
|
|
<Image src="https://example.com/photo.jpg" width={200} height={200} />
|
|
)
|
|
```
|
|
|
|
You can also use `objectFit` to control how the image fits its container:
|
|
|
|
```tsx
|
|
<Image src="https://example.com/photo.jpg" width="100%" height={300} objectFit="cover" />
|
|
```
|
|
|
|
### Sizing on native
|
|
|
|
`width` and `height` are Gui layout props. On native, they become React Native
|
|
Image styles. Remote images must resolve to a nonzero layout size, so use fixed
|
|
dimensions or place percentage-sized images inside a parent with defined dimensions:
|
|
|
|
```tsx
|
|
<View width={320} height={200}>
|
|
<Image
|
|
src="https://example.com/photo.jpg"
|
|
width="100%"
|
|
height="100%"
|
|
objectFit="cover"
|
|
/>
|
|
</View>
|
|
```
|
|
|
|
Gui converts a string `src` to `source={{ uri: src }}` on native. Layout
|
|
dimensions stay in `style`; they are not copied into the native source metadata.
|
|
React Native `source` objects remain supported for migration, but `src` is preferred.
|
|
|
|
## Using with expo-image
|
|
|
|
For better performance and features like blurhash placeholders and transitions,
|
|
you can use `createImage` to create a custom Image component with expo-image:
|
|
|
|
```tsx
|
|
import { Image as ExpoImage } from 'expo-image'
|
|
import { createImage } from '@hanzogui/image'
|
|
|
|
export const Image = createImage({
|
|
Component: ExpoImage,
|
|
resizeModePropName: 'contentFit',
|
|
objectPositionPropName: 'contentPosition',
|
|
})
|
|
```
|
|
|
|
Now you can use all expo-image props alongside Gui's unified API:
|
|
|
|
```tsx
|
|
const blurhash = '|rF?hV%2WCj[ayj[a|j[az...'
|
|
|
|
export default () => (
|
|
<Image
|
|
src="https://example.com/photo.jpg"
|
|
width={200}
|
|
height={300}
|
|
objectFit="cover"
|
|
placeholder={{ blurhash }}
|
|
transition={300}
|
|
/>
|
|
)
|
|
```
|
|
|
|
### createImage Options
|
|
|
|
<SimpleTable
|
|
headers={['Option', 'Type', 'Default', 'Description']}
|
|
rows={[
|
|
[
|
|
'Component',
|
|
'`ComponentType`',
|
|
'-',
|
|
'The underlying image component (expo-image, react-native-fast-image, etc.)',
|
|
],
|
|
[
|
|
'resizeModePropName',
|
|
'`string`',
|
|
"`'resizeMode'`",
|
|
"The prop name for resize mode. expo-image uses `'contentFit'`",
|
|
],
|
|
[
|
|
'objectPositionPropName',
|
|
'`string`',
|
|
'`undefined`',
|
|
"The prop name for object position. expo-image uses `'contentPosition'`",
|
|
],
|
|
[
|
|
'mapObjectFitToResizeMode',
|
|
'`function`',
|
|
'Default mapper',
|
|
"Custom function to map `objectFit` values to the component's resize mode",
|
|
],
|
|
[
|
|
'transformSource',
|
|
'`function`',
|
|
'Default transformer',
|
|
'Custom function to transform source props',
|
|
],
|
|
]}
|
|
/>
|
|
|
|
## Accessibility
|
|
|
|
Always provide an `alt` attribute describing the image content. For decorative images, use an empty string (`alt=""`).
|
|
|
|
```tsx
|
|
// meaningful image
|
|
<Image
|
|
src="/team-photo.jpg"
|
|
alt="The Gui team at React Conf 2024"
|
|
width={400}
|
|
height={300}
|
|
/>
|
|
|
|
// decorative image
|
|
<Image
|
|
src="/decorative-bg.jpg"
|
|
alt=""
|
|
width={400}
|
|
height={300}
|
|
/>
|
|
```
|
|
|
|
On React Native, use `accessible` and `accessibilityLabel` for screen reader support. See the [React Native Accessibility docs](https://reactnative.dev/docs/accessibility) for details.
|
|
|
|
```tsx
|
|
<Image
|
|
src="/avatar.jpg"
|
|
accessible
|
|
accessibilityLabel="User profile photo"
|
|
width={64}
|
|
height={64}
|
|
/>
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Image
|
|
|
|
Extends View with [Gui props](/docs/intro/props), plus:
|
|
|
|
<PropsTable
|
|
data={[
|
|
{
|
|
name: 'src',
|
|
type: 'string | number',
|
|
description:
|
|
'The image URL or native require() result. Preferred over `source` for better web alignment.',
|
|
},
|
|
{
|
|
name: 'alt',
|
|
type: 'string',
|
|
description:
|
|
'Alternative text describing the image for accessibility. Use empty string for decorative images.',
|
|
},
|
|
{
|
|
name: 'objectFit',
|
|
type: "'cover' | 'contain' | 'fill' | 'none' | 'scale-down'",
|
|
description:
|
|
'How the image should be resized to fit its container. Maps to CSS object-fit on web and resizeMode on native.',
|
|
},
|
|
{
|
|
name: 'objectPosition',
|
|
type: 'string',
|
|
description:
|
|
'How the image should be positioned within its container. On native, requires expo-image or similar for full support.',
|
|
},
|
|
{
|
|
name: 'source',
|
|
type: 'ImageSourcePropType',
|
|
description:
|
|
'Deprecated React Native source prop. It remains supported during migration; prefer `src`.',
|
|
},
|
|
{
|
|
name: 'resizeMode',
|
|
type: 'ImageResizeMode',
|
|
description: 'Deprecated. Use `objectFit` instead.',
|
|
},
|
|
]}
|
|
/>
|
|
|
|
### Web-only Props
|
|
|
|
These props pass through to the native `<img>` element on web:
|
|
|
|
<PropsTable
|
|
data={[
|
|
{
|
|
name: 'loading',
|
|
type: "'lazy' | 'eager'",
|
|
description:
|
|
'Lazy load images below the fold. Use eager (default) for above-the-fold images.',
|
|
},
|
|
{
|
|
name: 'decoding',
|
|
type: "'async' | 'sync' | 'auto'",
|
|
description:
|
|
'Hint for how the browser should decode the image. Use async for non-blocking decode.',
|
|
},
|
|
{
|
|
name: 'fetchPriority',
|
|
type: "'high' | 'low' | 'auto'",
|
|
description:
|
|
'Hint for fetch priority. Use high for LCP (largest contentful paint) images.',
|
|
},
|
|
{
|
|
name: 'srcSet',
|
|
type: 'string',
|
|
description:
|
|
'Comma-separated list of image sources with width descriptors for responsive images.',
|
|
},
|
|
{
|
|
name: 'sizes',
|
|
type: 'string',
|
|
description:
|
|
'Media conditions describing the image display size, used with srcSet.',
|
|
},
|
|
{
|
|
name: 'crossOrigin',
|
|
type: "'anonymous' | 'use-credentials'",
|
|
description: 'CORS setting for the image request.',
|
|
},
|
|
{
|
|
name: 'referrerPolicy',
|
|
type: 'string',
|
|
description: 'Referrer policy for the image request.',
|
|
},
|
|
]}
|
|
/>
|
|
|
|
### Accessibility Props
|
|
|
|
<PropsTable
|
|
data={[
|
|
{
|
|
name: 'alt',
|
|
type: 'string',
|
|
description:
|
|
'Alternative text for screen readers. Required for meaningful images, use empty string for decorative.',
|
|
},
|
|
{
|
|
name: 'accessible',
|
|
type: 'boolean',
|
|
description: 'Native only. Marks the image as an accessible element.',
|
|
},
|
|
{
|
|
name: 'accessibilityLabel',
|
|
type: 'string',
|
|
description:
|
|
'Native only. Label read by screen readers. Use with accessible={true}.',
|
|
},
|
|
{
|
|
name: 'aria-label',
|
|
type: 'string',
|
|
description: 'Overrides alt as the accessible name. Prefer using alt instead.',
|
|
},
|
|
{
|
|
name: 'aria-describedby',
|
|
type: 'string',
|
|
description: 'References an element providing extended description.',
|
|
},
|
|
{
|
|
name: 'aria-hidden',
|
|
type: 'boolean',
|
|
description: 'Hides the image from assistive technology. Alternative to alt="".',
|
|
},
|
|
{
|
|
name: 'role',
|
|
type: 'string',
|
|
description:
|
|
"Set to 'presentation' or 'none' for decorative images, or 'img' (default).",
|
|
},
|
|
]}
|
|
/>
|
|
|
|
<Notice theme="green">
|
|
Web props like `loading`, `srcSet`, and `fetchPriority` only apply on web. On native,
|
|
use expo-image via `createImage` for advanced features like blurhash placeholders and
|
|
priority loading.
|
|
</Notice>
|