@empathyco/x-components
Version:
Empathy X Components
178 lines (175 loc) • 5.76 kB
JavaScript
import { defineComponent, ref, watch, computed } from 'vue';
import { AnimationProp } from '../../types/animation-prop.js';
import '../animations/animate-clip-path/animate-clip-path.style.scss.js';
import '../animations/animate-scale/animate-scale.style.scss.js';
import '../animations/animate-translate/animate-translate.style.scss.js';
import '../animations/animate-width.vue2.js';
import '../animations/animate-width.vue3.js';
import '../animations/change-height.vue2.js';
import '../animations/collapse-height.vue2.js';
import '../animations/collapse-height.vue3.js';
import '../animations/collapse-width.vue2.js';
import '../animations/collapse-width.vue3.js';
import '../animations/cross-fade.vue2.js';
import '../animations/cross-fade.vue3.js';
import '../animations/fade-and-slide.vue2.js';
import '../animations/fade-and-slide.vue3.js';
import '../animations/fade.vue2.js';
import '../animations/fade.vue3.js';
import _sfc_main$1 from '../animations/no-animation.vue.js';
import '../animations/staggered-fade-and-slide.vue2.js';
import '../animations/staggered-fade-and-slide.vue3.js';
/**
* Component to be reused that renders an `<img>`.
*
* @public
*/
var _sfc_main = defineComponent({
name: 'BaseResultImage',
props: {
/** (Required) The {@link @empathyco/x-types#Result} information. */
result: {
type: Object,
required: true,
},
/**
* Animation to use when switching between the placeholder, the loaded image, or the failed
* image fallback.
*/
loadAnimation: {
type: AnimationProp,
default: () => _sfc_main$1,
},
/** Animation to use when switching between the loaded image and the hover image. */
hoverAnimation: {
type: AnimationProp,
},
/**
* Indicates if the next valid image should be displayed on hover.
*
* @public
*/
showNextImageOnHover: {
type: Boolean,
default: false,
},
},
setup(props) {
/**
* Copy of the images of the result.
*
* It is used as a queue of images to load, once an image loads/fails to load, it is removed
* from this array.
*
* @internal
*/
const pendingImages = ref([]);
/**
* Contains the images that have been loaded successfully.
*
* @internal
*/
const loadedImages = ref([]);
/**
* Indicates if the user is hovering the image.
*
* @internal
*/
const isHovering = ref(false);
/**
* Indicates if the user has hovered the image.
*
* @internal
*/
const userHasHoveredImage = ref(false);
/**.
* Styles to use inline in the image loader, to prevent override from CSS
*
* @internal
*/
const loaderStyles = {
position: 'absolute !important',
top: '0 !important',
left: '0 !important',
width: '100% !important',
height: '100% !important',
pointerEvents: 'none !important',
visibility: 'hidden !important',
};
/**
* Initializes images state and resets when the result's images change.
*
* @internal
*/
watch(() => props.result.images, () => {
pendingImages.value = [...(props.result.images ?? [])];
loadedImages.value = pendingImages.value.filter(image => loadedImages.value.includes(image));
}, { immediate: true });
/**
* Animation to be used.
*
* @returns The animation to be used, taking into account if the user has hovered the image.
*
* @internal
*/
const animation = computed(() => {
return userHasHoveredImage.value
? (props.hoverAnimation ?? props.loadAnimation)
: props.loadAnimation;
});
/**
* Gets the src from the result image.
*
* @returns The result image src.
*
* @internal
*/
const imageSrc = computed(() => {
return loadedImages.value[!props.showNextImageOnHover || !isHovering.value ? 0 : loadedImages.value.length - 1];
});
/**
* Indicates if the loader should try to load the next image.
*
* @returns True if it should try to load the next image.
*
* @internal
*/
const shouldLoadNextImage = computed(() => {
const numImagesToLoad = props.showNextImageOnHover && userHasHoveredImage.value ? 2 : 1;
return !!pendingImages.value.length && loadedImages.value.length < numImagesToLoad;
});
/**
* Sets an image as failed.
*
* @internal
*/
const flagImageAsFailed = () => {
pendingImages.value.shift();
};
/**
* Sets an image as loaded.
*
* @internal
*/
const flagImageLoaded = () => {
const image = pendingImages.value.shift();
if (image) {
loadedImages.value.push(image);
}
};
return {
pendingImages,
loadedImages,
isHovering,
userHasHoveredImage,
loaderStyles,
animation,
imageSrc,
shouldLoadNextImage,
flagImageAsFailed,
flagImageLoaded,
};
},
});
export { _sfc_main as default };
//# sourceMappingURL=base-result-image.vue2.js.map