Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#2871] fallback component integration for va-image #2874

Merged
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/docs/src/locales/en/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2645,7 +2645,7 @@
},
"slots": {
"title": "Status slots",
"text": "We're providing 3 status slots: `error` (visible when `src` path is incorrect), `loading` (visible when image is loading) and `placeholder` (works as both previous)."
"text": "We're providing 3 status slots: `error` (visible when `src` path is incorrect), `loading` (visible when image is loading) and `placeholder` (works as both previous). As an alternative for error handling, we provide the `fallback-icon`, `fallback-text`, `fallback-image` and `fallback-renderer` props, that will be called if error slot wasn't passed."
},
aluarius marked this conversation as resolved.
Show resolved Hide resolved
"srcSet": {
"title": "Srcset",
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/locales/ru/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -2519,7 +2519,7 @@
},
"slots": {
"title": "Слоты состояний",
"text": "Мы предоставляем 3 слота состояния: `error` (содержимое отображается когда `src` некорректен), `loading` (содержимое отображается когда изображение грузится) and `placeholder` (универсальное решение, заменяющее 2 предыдущих)."
"text": "Мы предоставляем 3 слота состояния: `error` (содержимое отображается когда `src` некорректен), `loading` (содержимое отображается когда изображение грузится) and `placeholder` (универсальное решение, заменяющее 2 предыдущих). Также, в качестве альтернативного способа обработки ошибок, вы можете передавать свойства `fallback-icon`, `fallback-text`, `fallback-image` и `fallback-renderer`, которые будут отрабатывать, если `error` слот не был передан."
},
"srcSet": {
"title": "Srcset",
Expand Down
40 changes: 24 additions & 16 deletions packages/docs/src/page-configs/ui-elements/image/examples/Slots.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,30 @@
Wrong path
</va-button>
</div>
<va-image
class="flex flex-col md6 lg4"
:src="slotImagePath"
@loaded="consoleLog"
@error="consoleLog"
>
<template #loader>
<va-progress-circle indeterminate />
</template>

<template #error>
<div class="p-8 flex items-center justify-center bg-red-300 rounded-3xl">
<va-icon name="close" color="danger" :size="32" />
</div>
</template>
</va-image>
<div class="row space-x-4">
<va-image
class="flex flex-col md6 lg4"
:src="slotImagePath"
@loaded="consoleLog"
@error="consoleLog"
>
<template #loader>
<va-progress-circle indeterminate />
</template>

<template #error>
<div class="p-8 flex items-center justify-center bg-red-300 rounded-3xl">
<va-icon name="close" color="danger" :size="32" />
</div>
</template>
</va-image>

<va-image
class="flex flex-col md6 lg4"
:src="slotImagePath"
fallback-text="Fallback will work if error slot wasn't passed"
/>
</div>
</template>

<script setup>
Expand Down
8 changes: 7 additions & 1 deletion packages/ui/src/components/va-image/VaImage.demo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,19 @@
</va-image>

<va-image
class="image"
class="image mb-2"
:src="slotImagePath"
>
<template #placeholder>
Placeholder (both error and loading states)
</template>
</va-image>

<va-image
class="image"
:src="slotImagePath"
fallback-text="Fallback text"
/>
</VbCard>

<VbCard title="Default slot">
Expand Down
25 changes: 20 additions & 5 deletions packages/ui/src/components/va-image/VaImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@
</div>

<div
v-if="isError && $slots.error"
v-if="isError && ($slots.error || isAnyFallbackPassed)"
class="va-image__error"
>
<slot name="error" />
<slot name="error">
<va-fallback v-bind="fallbackProps" @fallback="$emit('fallback')" />
</slot>
</div>

<div
Expand Down Expand Up @@ -58,20 +60,26 @@
import { defineComponent, ref, computed, watch, nextTick, onBeforeUnmount, type PropType, onBeforeMount } from 'vue'

import { VaAspectRatio } from '../va-aspect-ratio'
import { VaFallback } from '../va-fallback'

import { useNativeImgAttributes, useNativeImgAttributesProps } from './hooks/useNativeImgAttributes'
import { useComponentPresetProp, useDeprecated } from '../../composables'

import { extractComponentProps, filterComponentProps } from '../../utils/component-options'

const VaFallbackProps = extractComponentProps(VaFallback)

export default defineComponent({
name: 'VaImage',

components: { VaAspectRatio },
components: { VaAspectRatio, VaFallback },

emits: ['loaded', 'error'],
emits: ['loaded', 'error', 'fallback'],

props: {
...useComponentPresetProp,
...useNativeImgAttributesProps,
...VaFallbackProps,
ratio: {
type: [Number, String] as PropType<number | 'auto'>,
default: 'auto',
Expand Down Expand Up @@ -164,7 +172,8 @@ export default defineComponent({
watch(() => props.src, init)

const isPlaceholderShown = computed(() =>
((isLoading.value && !slots?.loader?.()) || (isError.value && !slots?.error?.())) && (slots?.placeholder?.() || props.placeholderSrc))
((isLoading.value && !slots?.loader?.()) || (isError.value && (!slots?.error?.() && !isAnyFallbackPassed.value))) &&
aluarius marked this conversation as resolved.
Show resolved Hide resolved
(slots?.placeholder?.() || props.placeholderSrc))

const isSuccessfullyLoaded = computed(() => !(isLoading.value || isError.value))

Expand All @@ -176,6 +185,9 @@ export default defineComponent({
ratio: props.ratio,
}))

const fallbackProps = filterComponentProps(VaFallbackProps)
const isAnyFallbackPassed = computed(() => !!Object.values(fallbackProps.value).filter((prop) => prop).length)

// TODO: refactor (just v-bind fit prop to CSS) in 1.7.0
const fitComputed = computed(() => {
if (props.contain) { return 'contain' }
Expand All @@ -193,6 +205,9 @@ export default defineComponent({
isSuccessfullyLoaded,
imgAttributesComputed,
aspectRationAttributesComputed,

isAnyFallbackPassed,
fallbackProps,
}
},
})
Expand Down