import type { CSSProperties, ImgHTMLAttributes, Ref } from 'react';
import React from 'react';
import classNames from 'classnames';
import { Image as CoreImage, useTranslations } from '@shoptet/ui-core-web';
import type { Exact, SafeExtract, SafeOmit } from '@shoptet/utils';
import { omit, pick } from '@shoptet/utils';
import type { Size } from '../../tokens/types';
import { Icon } from '../Icon/Icon';
import { Text } from '../Typography/Text/Text';
import { dictionary } from './dictionary';
type ImageContainerProps = SafeOmit<
ImgHTMLAttributes,
'className' | 'src' | 'srcSet' | 'alt' | 'style'
>;
export interface ImageProps extends ImageContainerProps {
/**
* Ref for the underlying image element.
*/
ref?: Ref;
/**
* Image source URL.
*/
src: string | null | undefined;
/**
* The `srcSet` attribute for the image.
*/
srcSet?: string | undefined;
/**
* Alternative text for the image. Use an empty string for decorative images.
*/
alt: string;
/**
* Custom aspect ratio for the fixed layout.
* @default '3 / 2'
*/
aspectRatio?: `${number} / ${number}` | number;
/**
* Whether the image should use its intrinsic aspect ratio.
* @default false
*/
responsive?: boolean;
/**
* Controls how the image fits inside its box.
* @default 'contain'
*/
fit?: 'contain' | 'cover';
/**
* Sets predefined image width.
* @default 'md'
*/
size?: SafeExtract;
}
const hiddenImgStyle: CSSProperties = { opacity: 0, transition: 'none' };
export const Image = ({
alt: altProp,
aspectRatio = '3 / 2',
fit = 'contain',
ref,
responsive = false,
size = 'md',
src: srcProp,
srcSet,
...rest
}: ImageProps) => {
rest satisfies Exact;
const src = (srcProp ?? '').trim();
const translations = useTranslations(dictionary);
const alt = altProp === '' ? null : altProp;
const aspectRatioValue = typeof aspectRatio === 'number' ? `${aspectRatio}` : aspectRatio;
return (
(state.loadingState === 'success' ? {} : hiddenImgStyle)}
/>
{({ state, props }) =>
({
error: (
{alt === null ? translations.loadingError : alt}
),
initial: (
),
success: ,
pending: ,
})[state.loadingState]
}
);
};