@12-apps/ui 6.39.0 → 6.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/components/data-display/LazyImage/LazyImage.js +1 -1
- package/dist/_internal/components/data-display/index.js +1 -1
- package/dist/_internal/components/index.js +1 -1
- package/dist/{chunk-T7DE44SP.js → chunk-FF2D7V7T.js} +6 -4
- package/dist/chunk-FF2D7V7T.js.map +1 -0
- package/dist/data-display/LazyImage.js +1 -1
- package/dist/types/components/data-display/LazyImage/LazyImage.d.ts.map +1 -1
- package/dist/types/components/data-display/LazyImage/LazyImage.types.d.ts +3 -1
- package/dist/types/components/data-display/LazyImage/LazyImage.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/data-display/LazyImage/LazyImage.tsx +5 -3
- package/src/components/data-display/LazyImage/LazyImage.types.ts +3 -1
- package/dist/chunk-T7DE44SP.js.map +0 -1
|
@@ -91,7 +91,7 @@ import "../../../chunk-S5UY5U73.js";
|
|
|
91
91
|
import "../../../chunk-5ZFO7ROE.js";
|
|
92
92
|
import {
|
|
93
93
|
LazyImage
|
|
94
|
-
} from "../../../chunk-
|
|
94
|
+
} from "../../../chunk-FF2D7V7T.js";
|
|
95
95
|
import "../../../chunk-HCT5ELST.js";
|
|
96
96
|
import "../../../chunk-724ZONOL.js";
|
|
97
97
|
import "../../../chunk-UM35GGCS.js";
|
|
@@ -477,7 +477,7 @@ import "../../chunk-S5UY5U73.js";
|
|
|
477
477
|
import "../../chunk-5ZFO7ROE.js";
|
|
478
478
|
import {
|
|
479
479
|
LazyImage
|
|
480
|
-
} from "../../chunk-
|
|
480
|
+
} from "../../chunk-FF2D7V7T.js";
|
|
481
481
|
import "../../chunk-HCT5ELST.js";
|
|
482
482
|
import "../../chunk-724ZONOL.js";
|
|
483
483
|
import "../../chunk-UM35GGCS.js";
|
|
@@ -70,7 +70,7 @@ var SkeletonIndicator = ({ props }) => {
|
|
|
70
70
|
height: styleLength(theme, props.height || 200),
|
|
71
71
|
animation: props.skeletonProps.animation || "pulse",
|
|
72
72
|
intensity: props.skeletonProps.intensity,
|
|
73
|
-
borderRadius: props.borderRadius,
|
|
73
|
+
borderRadius: styleLength(theme, props.borderRadius),
|
|
74
74
|
"data-testid": `${props["data-testid"]}-skeleton`
|
|
75
75
|
}
|
|
76
76
|
);
|
|
@@ -137,7 +137,7 @@ var ErrorFallback = ({ props, metrics }) => {
|
|
|
137
137
|
return /* @__PURE__ */ jsx(
|
|
138
138
|
FallbackContainer,
|
|
139
139
|
{
|
|
140
|
-
sx: { width: sxLength(theme, width), height: sxLength(theme, height), borderRadius },
|
|
140
|
+
sx: { width: sxLength(theme, width), height: sxLength(theme, height), borderRadius: styleLength(theme, borderRadius) },
|
|
141
141
|
"data-testid": `${testId}-fallback`,
|
|
142
142
|
children: fallback
|
|
143
143
|
}
|
|
@@ -172,7 +172,9 @@ var LazyImage = React.memo(function LazyImage2(rawProps) {
|
|
|
172
172
|
sx: {
|
|
173
173
|
width: sxLength(theme, width || "auto"),
|
|
174
174
|
height: sxLength(theme, height || "auto"),
|
|
175
|
-
|
|
175
|
+
// The same px length the image gets (`metrics`): in `sx` a bare number
|
|
176
|
+
// would be a multiple of `shape.borderRadius`, and this box clips (FUT-2656).
|
|
177
|
+
borderRadius: metrics.borderRadius
|
|
176
178
|
},
|
|
177
179
|
"data-testid": testId,
|
|
178
180
|
children: [
|
|
@@ -215,4 +217,4 @@ LazyImage.displayName = "LazyImage";
|
|
|
215
217
|
export {
|
|
216
218
|
LazyImage
|
|
217
219
|
};
|
|
218
|
-
//# sourceMappingURL=chunk-
|
|
220
|
+
//# sourceMappingURL=chunk-FF2D7V7T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/LazyImage/LazyImage.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport CircularProgress from '@mui/material/CircularProgress/index.js';\nimport { styled, useTheme, type Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\nimport { Skeleton } from '../../layout/Skeleton';\nimport type { ResolvedLazyImageProps } from './LazyImage.hooks';\nimport { imgPassThrough, resolveLazyImageProps, useLazyImage } from './LazyImage.hooks';\nimport type { LazyImageProps } from './LazyImage.types';\nimport { sheen } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\n\nconst ImageContainer = styled(Box)(() => ({\n position: 'relative',\n display: 'inline-block',\n overflow: 'hidden',\n}));\n\nconst StyledImage = styled('img')<{\n fadeIn?: boolean;\n fadeInDuration?: number;\n isLoaded?: boolean;\n}>(({ fadeIn, fadeInDuration = 300, isLoaded }) => ({\n display: 'block',\n maxWidth: '100%',\n height: 'auto',\n opacity: fadeIn ? (isLoaded ? 1 : 0) : 1,\n transition: fadeIn ? `opacity ${fadeInDuration}ms ease-in-out` : 'none',\n}));\n\nconst SpinnerOverlay = styled(Box)(({ theme }) => ({\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: sheen(theme, 0.8),\n borderRadius: '50%',\n padding: theme.spacing(1),\n}));\n\nconst FallbackContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: theme.palette.action.disabledBackground,\n color: theme.palette.text.secondary,\n width: '100%',\n height: '100%',\n position: 'absolute',\n top: 0,\n left: 0,\n}));\n\ntype Length = number | string | undefined;\n\n/** A length prop as React `style` and MUI's `Skeleton` read it: a number is design px. */\nconst styleLength = (theme: Theme, value: Length): string | undefined =>\n typeof value === 'number' ? rem(theme, value) : value;\n\n/**\n * A length prop as `sx` reads it on a width or height: a number of 1 or less is\n * a fraction of the parent, and that stays so; any other number is design px.\n */\nconst sxLength = (theme: Theme, value: Length): string | undefined => {\n if (typeof value !== 'number') return value;\n return value <= 1 && value !== 0 ? `${value * 100}%` : rem(theme, value);\n};\n\n/** The box the image occupies, as CSS, shared by the real image and every stand-in for it. */\ninterface BoxMetrics {\n width?: string;\n height?: string;\n objectFit: NonNullable<LazyImageProps['objectFit']>;\n objectPosition: string;\n borderRadius?: string;\n}\n\ninterface IndicatorProps {\n props: ResolvedLazyImageProps;\n metrics: BoxMetrics;\n}\n\nconst SkeletonIndicator: React.FC<IndicatorProps> = ({ props }) => {\n const theme = useTheme();\n return (\n <Skeleton\n variant=\"rectangular\"\n width={styleLength(theme, props.width || '100%')}\n height={styleLength(theme, props.height || 200)}\n animation={props.skeletonProps.animation || 'pulse'}\n intensity={props.skeletonProps.intensity}\n borderRadius={styleLength(theme, props.borderRadius)}\n data-testid={`${props['data-testid']}-skeleton`}\n />\n );\n};\n\nconst SpinnerIndicator: React.FC<IndicatorProps> = ({ props }) => {\n const theme = useTheme();\n const { spinnerProps } = props;\n\n return (\n <SpinnerOverlay>\n <CircularProgress\n size={styleLength(theme, spinnerProps.size || 40)}\n thickness={spinnerProps.thickness || 4}\n sx={{ color: spinnerProps.color || theme.palette.primary.main }}\n data-testid={`${props['data-testid']}-spinner`}\n />\n </SpinnerOverlay>\n );\n};\n\nconst PlaceholderIndicator: React.FC<IndicatorProps & { hasSrc: boolean }> = ({\n props,\n metrics,\n hasSrc,\n}) => {\n // Once a src has been chosen the real <img> is on screen, so the placeholder\n // would only stack behind it.\n if (!props.placeholder || hasSrc) return null;\n\n return (\n <StyledImage\n src={props.placeholder}\n alt={`${props.alt} (loading)`}\n style={metrics}\n data-testid={`${props['data-testid']}-placeholder`}\n />\n );\n};\n\nconst LoadingIndicator: React.FC<\n IndicatorProps & { kind: NonNullable<LazyImageProps['loadingState']>; hasSrc: boolean }\n> = ({ kind, hasSrc, ...rest }) => {\n switch (kind) {\n case 'skeleton':\n return <SkeletonIndicator {...rest} />;\n case 'spinner':\n return <SpinnerIndicator {...rest} />;\n case 'placeholder':\n return <PlaceholderIndicator {...rest} hasSrc={hasSrc} />;\n default:\n return null;\n }\n};\n\nconst ErrorFallback: React.FC<IndicatorProps> = ({ props, metrics }) => {\n const theme = useTheme();\n const { alt, fallback, width, height, borderRadius } = props;\n const testId = props['data-testid'];\n\n if (!fallback) return null;\n\n if (typeof fallback === 'string') {\n return (\n <StyledImage\n src={fallback}\n alt={`${alt} (fallback)`}\n style={metrics}\n fadeIn={false}\n isLoaded={true}\n data-testid={`${testId}-fallback`}\n />\n );\n }\n\n return (\n <FallbackContainer\n sx={{ width: sxLength(theme, width), height: sxLength(theme, height), borderRadius: styleLength(theme, borderRadius) }}\n data-testid={`${testId}-fallback`}\n >\n {fallback}\n </FallbackContainer>\n );\n};\n\n/**\n * LazyImage component with enhanced features for optimized image loading\n * Supports lazy loading, placeholders, error handling, and various loading states\n */\nexport const LazyImage = React.memo<LazyImageProps>(function LazyImage(rawProps) {\n const props = resolveLazyImageProps(rawProps);\n const theme = useTheme();\n const {\n state,\n containerRef,\n effectiveLoadingState,\n handleImageLoad,\n handleImageError,\n showImage,\n showLoading,\n } = useLazyImage(props);\n\n const { width, height, borderRadius, alt } = props;\n const testId = props['data-testid'];\n const metrics: BoxMetrics = {\n width: styleLength(theme, width),\n height: styleLength(theme, height),\n objectFit: props.objectFit,\n objectPosition: props.objectPosition,\n borderRadius: styleLength(theme, borderRadius),\n };\n\n return (\n <ImageContainer\n ref={containerRef}\n className={props.className}\n sx={{\n width: sxLength(theme, width || 'auto'),\n height: sxLength(theme, height || 'auto'),\n // The same px length the image gets (`metrics`): in `sx` a bare number\n // would be a multiple of `shape.borderRadius`, and this box clips (FUT-2656).\n borderRadius: metrics.borderRadius,\n }}\n data-testid={testId}\n >\n {showLoading && (\n <LoadingIndicator\n kind={effectiveLoadingState}\n props={props}\n metrics={metrics}\n hasSrc={Boolean(state.currentSrc)}\n />\n )}\n\n {showImage && (\n <StyledImage\n src={state.currentSrc || undefined}\n alt={alt}\n onLoad={handleImageLoad}\n onError={handleImageError}\n fadeIn={props.fadeIn}\n fadeInDuration={props.fadeInDuration}\n isLoaded={!state.isLoading}\n decoding={props.decoding}\n loading={props.lazy ? 'lazy' : props.loading}\n style={{ ...metrics, ...props.sx }}\n aria-label={props['aria-label'] || alt}\n aria-describedby={props['aria-describedby']}\n role={props.role}\n data-testid={`${testId}-img`}\n {...imgPassThrough(props)}\n />\n )}\n\n {state.hasError && <ErrorFallback props={props} metrics={metrics} />}\n </ImageContainer>\n );\n});\n\nLazyImage.displayName = 'LazyImage';\n"],"mappings":"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","names":["LazyImage"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LazyImage.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/LazyImage/LazyImage.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA4KxD;;;GAGG;AACH,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"LazyImage.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/LazyImage/LazyImage.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA4KxD;;;GAGG;AACH,eAAO,MAAM,SAAS,4CAoEpB,CAAC"}
|
|
@@ -51,7 +51,9 @@ export interface LazyImageProps extends React.ImgHTMLAttributes<HTMLImageElement
|
|
|
51
51
|
*/
|
|
52
52
|
objectPosition?: string;
|
|
53
53
|
/**
|
|
54
|
-
* Border radius
|
|
54
|
+
* Border radius: a number is design px, scaled with the theme's type scale,
|
|
55
|
+
* and rounds the image, its clipping box, its skeleton and its fallback alike;
|
|
56
|
+
* a string is any CSS length and passes through untouched.
|
|
55
57
|
*/
|
|
56
58
|
borderRadius?: number | string;
|
|
57
59
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LazyImage.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/LazyImage/LazyImage.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;AACtF,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;AAEpF,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;IAC/E;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAEpC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IAErC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAE/B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB
|
|
1
|
+
{"version":3,"file":"LazyImage.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/LazyImage/LazyImage.types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -91,7 +91,7 @@ const SkeletonIndicator: React.FC<IndicatorProps> = ({ props }) => {
|
|
|
91
91
|
height={styleLength(theme, props.height || 200)}
|
|
92
92
|
animation={props.skeletonProps.animation || 'pulse'}
|
|
93
93
|
intensity={props.skeletonProps.intensity}
|
|
94
|
-
borderRadius={props.borderRadius}
|
|
94
|
+
borderRadius={styleLength(theme, props.borderRadius)}
|
|
95
95
|
data-testid={`${props['data-testid']}-skeleton`}
|
|
96
96
|
/>
|
|
97
97
|
);
|
|
@@ -169,7 +169,7 @@ const ErrorFallback: React.FC<IndicatorProps> = ({ props, metrics }) => {
|
|
|
169
169
|
|
|
170
170
|
return (
|
|
171
171
|
<FallbackContainer
|
|
172
|
-
sx={{ width: sxLength(theme, width), height: sxLength(theme, height), borderRadius }}
|
|
172
|
+
sx={{ width: sxLength(theme, width), height: sxLength(theme, height), borderRadius: styleLength(theme, borderRadius) }}
|
|
173
173
|
data-testid={`${testId}-fallback`}
|
|
174
174
|
>
|
|
175
175
|
{fallback}
|
|
@@ -211,7 +211,9 @@ export const LazyImage = React.memo<LazyImageProps>(function LazyImage(rawProps)
|
|
|
211
211
|
sx={{
|
|
212
212
|
width: sxLength(theme, width || 'auto'),
|
|
213
213
|
height: sxLength(theme, height || 'auto'),
|
|
214
|
-
|
|
214
|
+
// The same px length the image gets (`metrics`): in `sx` a bare number
|
|
215
|
+
// would be a multiple of `shape.borderRadius`, and this box clips (FUT-2656).
|
|
216
|
+
borderRadius: metrics.borderRadius,
|
|
215
217
|
}}
|
|
216
218
|
data-testid={testId}
|
|
217
219
|
>
|
|
@@ -63,7 +63,9 @@ export interface LazyImageProps extends React.ImgHTMLAttributes<HTMLImageElement
|
|
|
63
63
|
objectPosition?: string;
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
|
-
* Border radius
|
|
66
|
+
* Border radius: a number is design px, scaled with the theme's type scale,
|
|
67
|
+
* and rounds the image, its clipping box, its skeleton and its fallback alike;
|
|
68
|
+
* a string is any CSS length and passes through untouched.
|
|
67
69
|
*/
|
|
68
70
|
borderRadius?: number | string;
|
|
69
71
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/LazyImage/LazyImage.tsx"],"sourcesContent":["import Box from '@mui/material/Box/index.js';\nimport CircularProgress from '@mui/material/CircularProgress/index.js';\nimport { styled, useTheme, type Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\nimport { Skeleton } from '../../layout/Skeleton';\nimport type { ResolvedLazyImageProps } from './LazyImage.hooks';\nimport { imgPassThrough, resolveLazyImageProps, useLazyImage } from './LazyImage.hooks';\nimport type { LazyImageProps } from './LazyImage.types';\nimport { sheen } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\n\nconst ImageContainer = styled(Box)(() => ({\n position: 'relative',\n display: 'inline-block',\n overflow: 'hidden',\n}));\n\nconst StyledImage = styled('img')<{\n fadeIn?: boolean;\n fadeInDuration?: number;\n isLoaded?: boolean;\n}>(({ fadeIn, fadeInDuration = 300, isLoaded }) => ({\n display: 'block',\n maxWidth: '100%',\n height: 'auto',\n opacity: fadeIn ? (isLoaded ? 1 : 0) : 1,\n transition: fadeIn ? `opacity ${fadeInDuration}ms ease-in-out` : 'none',\n}));\n\nconst SpinnerOverlay = styled(Box)(({ theme }) => ({\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: sheen(theme, 0.8),\n borderRadius: '50%',\n padding: theme.spacing(1),\n}));\n\nconst FallbackContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: theme.palette.action.disabledBackground,\n color: theme.palette.text.secondary,\n width: '100%',\n height: '100%',\n position: 'absolute',\n top: 0,\n left: 0,\n}));\n\ntype Length = number | string | undefined;\n\n/** A length prop as React `style` and MUI's `Skeleton` read it: a number is design px. */\nconst styleLength = (theme: Theme, value: Length): string | undefined =>\n typeof value === 'number' ? rem(theme, value) : value;\n\n/**\n * A length prop as `sx` reads it on a width or height: a number of 1 or less is\n * a fraction of the parent, and that stays so; any other number is design px.\n */\nconst sxLength = (theme: Theme, value: Length): string | undefined => {\n if (typeof value !== 'number') return value;\n return value <= 1 && value !== 0 ? `${value * 100}%` : rem(theme, value);\n};\n\n/** The box the image occupies, as CSS, shared by the real image and every stand-in for it. */\ninterface BoxMetrics {\n width?: string;\n height?: string;\n objectFit: NonNullable<LazyImageProps['objectFit']>;\n objectPosition: string;\n borderRadius?: string;\n}\n\ninterface IndicatorProps {\n props: ResolvedLazyImageProps;\n metrics: BoxMetrics;\n}\n\nconst SkeletonIndicator: React.FC<IndicatorProps> = ({ props }) => {\n const theme = useTheme();\n return (\n <Skeleton\n variant=\"rectangular\"\n width={styleLength(theme, props.width || '100%')}\n height={styleLength(theme, props.height || 200)}\n animation={props.skeletonProps.animation || 'pulse'}\n intensity={props.skeletonProps.intensity}\n borderRadius={props.borderRadius}\n data-testid={`${props['data-testid']}-skeleton`}\n />\n );\n};\n\nconst SpinnerIndicator: React.FC<IndicatorProps> = ({ props }) => {\n const theme = useTheme();\n const { spinnerProps } = props;\n\n return (\n <SpinnerOverlay>\n <CircularProgress\n size={styleLength(theme, spinnerProps.size || 40)}\n thickness={spinnerProps.thickness || 4}\n sx={{ color: spinnerProps.color || theme.palette.primary.main }}\n data-testid={`${props['data-testid']}-spinner`}\n />\n </SpinnerOverlay>\n );\n};\n\nconst PlaceholderIndicator: React.FC<IndicatorProps & { hasSrc: boolean }> = ({\n props,\n metrics,\n hasSrc,\n}) => {\n // Once a src has been chosen the real <img> is on screen, so the placeholder\n // would only stack behind it.\n if (!props.placeholder || hasSrc) return null;\n\n return (\n <StyledImage\n src={props.placeholder}\n alt={`${props.alt} (loading)`}\n style={metrics}\n data-testid={`${props['data-testid']}-placeholder`}\n />\n );\n};\n\nconst LoadingIndicator: React.FC<\n IndicatorProps & { kind: NonNullable<LazyImageProps['loadingState']>; hasSrc: boolean }\n> = ({ kind, hasSrc, ...rest }) => {\n switch (kind) {\n case 'skeleton':\n return <SkeletonIndicator {...rest} />;\n case 'spinner':\n return <SpinnerIndicator {...rest} />;\n case 'placeholder':\n return <PlaceholderIndicator {...rest} hasSrc={hasSrc} />;\n default:\n return null;\n }\n};\n\nconst ErrorFallback: React.FC<IndicatorProps> = ({ props, metrics }) => {\n const theme = useTheme();\n const { alt, fallback, width, height, borderRadius } = props;\n const testId = props['data-testid'];\n\n if (!fallback) return null;\n\n if (typeof fallback === 'string') {\n return (\n <StyledImage\n src={fallback}\n alt={`${alt} (fallback)`}\n style={metrics}\n fadeIn={false}\n isLoaded={true}\n data-testid={`${testId}-fallback`}\n />\n );\n }\n\n return (\n <FallbackContainer\n sx={{ width: sxLength(theme, width), height: sxLength(theme, height), borderRadius }}\n data-testid={`${testId}-fallback`}\n >\n {fallback}\n </FallbackContainer>\n );\n};\n\n/**\n * LazyImage component with enhanced features for optimized image loading\n * Supports lazy loading, placeholders, error handling, and various loading states\n */\nexport const LazyImage = React.memo<LazyImageProps>(function LazyImage(rawProps) {\n const props = resolveLazyImageProps(rawProps);\n const theme = useTheme();\n const {\n state,\n containerRef,\n effectiveLoadingState,\n handleImageLoad,\n handleImageError,\n showImage,\n showLoading,\n } = useLazyImage(props);\n\n const { width, height, borderRadius, alt } = props;\n const testId = props['data-testid'];\n const metrics: BoxMetrics = {\n width: styleLength(theme, width),\n height: styleLength(theme, height),\n objectFit: props.objectFit,\n objectPosition: props.objectPosition,\n borderRadius: styleLength(theme, borderRadius),\n };\n\n return (\n <ImageContainer\n ref={containerRef}\n className={props.className}\n sx={{\n width: sxLength(theme, width || 'auto'),\n height: sxLength(theme, height || 'auto'),\n borderRadius,\n }}\n data-testid={testId}\n >\n {showLoading && (\n <LoadingIndicator\n kind={effectiveLoadingState}\n props={props}\n metrics={metrics}\n hasSrc={Boolean(state.currentSrc)}\n />\n )}\n\n {showImage && (\n <StyledImage\n src={state.currentSrc || undefined}\n alt={alt}\n onLoad={handleImageLoad}\n onError={handleImageError}\n fadeIn={props.fadeIn}\n fadeInDuration={props.fadeInDuration}\n isLoaded={!state.isLoading}\n decoding={props.decoding}\n loading={props.lazy ? 'lazy' : props.loading}\n style={{ ...metrics, ...props.sx }}\n aria-label={props['aria-label'] || alt}\n aria-describedby={props['aria-describedby']}\n role={props.role}\n data-testid={`${testId}-img`}\n {...imgPassThrough(props)}\n />\n )}\n\n {state.hasError && <ErrorFallback props={props} metrics={metrics} />}\n </ImageContainer>\n );\n});\n\nLazyImage.displayName = 'LazyImage';\n"],"mappings":"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","names":["LazyImage"]}
|