@redseed/redseed-ui-vue3 2.11.13 → 2.11.15
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/package.json +1 -1
- package/src/components/Image/Image.vue +53 -11
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref, computed } from 'vue'
|
|
2
|
+
import { ref, computed, watch } from 'vue'
|
|
3
3
|
import { useImage } from '@vueuse/core'
|
|
4
4
|
import { PhotoIcon } from '@heroicons/vue/24/outline'
|
|
5
5
|
|
|
@@ -24,11 +24,15 @@ const props = defineProps({
|
|
|
24
24
|
type: Boolean,
|
|
25
25
|
default: false,
|
|
26
26
|
},
|
|
27
|
+
alt: {
|
|
28
|
+
type: String,
|
|
29
|
+
default: '',
|
|
30
|
+
},
|
|
27
31
|
})
|
|
28
32
|
|
|
29
|
-
const large = computed(() => props.largeUrl
|
|
30
|
-
const medium = computed(() => props.mediumUrl
|
|
31
|
-
const small = computed(() => props.smallUrl
|
|
33
|
+
const large = computed(() => props.largeUrl || props.originalUrl)
|
|
34
|
+
const medium = computed(() => props.mediumUrl || props.originalUrl)
|
|
35
|
+
const small = computed(() => props.smallUrl || props.originalUrl)
|
|
32
36
|
|
|
33
37
|
const originalOptions = computed(() => ({
|
|
34
38
|
src: props.originalUrl,
|
|
@@ -51,21 +55,53 @@ const largeImage = ref(useImage(largeOptions.value))
|
|
|
51
55
|
const mediumImage = ref(useImage(mediumOptions.value))
|
|
52
56
|
const smallImage = ref(useImage(smallOptions.value))
|
|
53
57
|
|
|
58
|
+
const isEmpty = computed(() => !props.originalUrl)
|
|
59
|
+
|
|
54
60
|
const isLoading = computed(() => {
|
|
61
|
+
if (isEmpty.value) return false
|
|
62
|
+
|
|
55
63
|
return originalImage.value.isLoading
|
|
56
64
|
|| largeImage.value.isLoading
|
|
57
65
|
|| mediumImage.value.isLoading
|
|
58
66
|
|| smallImage.value.isLoading
|
|
59
67
|
})
|
|
60
68
|
|
|
69
|
+
const isReady = computed(() => {
|
|
70
|
+
if (isEmpty.value) return false
|
|
71
|
+
|
|
72
|
+
return originalImage.value.isReady
|
|
73
|
+
&& largeImage.value.isReady
|
|
74
|
+
&& mediumImage.value.isReady
|
|
75
|
+
&& smallImage.value.isReady
|
|
76
|
+
})
|
|
77
|
+
|
|
61
78
|
const error = computed(() => {
|
|
79
|
+
if (isEmpty.value) return false
|
|
80
|
+
|
|
62
81
|
return originalImage.value.error
|
|
82
|
+
|| largeImage.value.error
|
|
83
|
+
|| mediumImage.value.error
|
|
84
|
+
|| smallImage.value.error
|
|
63
85
|
})
|
|
64
86
|
|
|
87
|
+
const emit = defineEmits(['loading', 'error', 'ready'])
|
|
88
|
+
|
|
89
|
+
watch(isLoading, () => {
|
|
90
|
+
if (isLoading.value) emit('loading', isLoading.value)
|
|
91
|
+
}, { immediate: true, flush: 'post' })
|
|
92
|
+
|
|
93
|
+
watch(error, () => {
|
|
94
|
+
if (error.value) emit('error', error.value)
|
|
95
|
+
}, { immediate: true, flush: 'post' })
|
|
96
|
+
|
|
97
|
+
watch(isReady, () => {
|
|
98
|
+
if (isReady.value) emit('ready', isReady.value)
|
|
99
|
+
}, { immediate: true, flush: 'post' })
|
|
100
|
+
|
|
65
101
|
const sources = computed(() => {
|
|
66
102
|
return [
|
|
67
103
|
{
|
|
68
|
-
media: '(min-width:
|
|
104
|
+
media: '(min-width:1280px)',
|
|
69
105
|
srcset: large.value
|
|
70
106
|
},
|
|
71
107
|
{
|
|
@@ -83,13 +119,15 @@ const imageClass = computed(() => [
|
|
|
83
119
|
'rsui-image',
|
|
84
120
|
{
|
|
85
121
|
'rsui-image--rounded': props.rounded,
|
|
122
|
+
'rsui-image--empty': isEmpty.value,
|
|
123
|
+
'rsui-image--error': error.value,
|
|
86
124
|
}
|
|
87
125
|
|
|
88
126
|
])
|
|
89
127
|
</script>
|
|
90
128
|
<template>
|
|
91
129
|
<div :class="imageClass">
|
|
92
|
-
<div v-if="
|
|
130
|
+
<div v-if="isEmpty"
|
|
93
131
|
class="rsui-image__empty"
|
|
94
132
|
>
|
|
95
133
|
<slot name="empty-icon">
|
|
@@ -99,9 +137,7 @@ const imageClass = computed(() => [
|
|
|
99
137
|
<div v-else-if="isLoading"
|
|
100
138
|
class="rsui-image__message"
|
|
101
139
|
>
|
|
102
|
-
<slot name="loading">
|
|
103
|
-
Loading...
|
|
104
|
-
</slot>
|
|
140
|
+
<slot name="loading"></slot>
|
|
105
141
|
</div>
|
|
106
142
|
<div v-else-if="error"
|
|
107
143
|
class="rsui-image__message"
|
|
@@ -116,16 +152,22 @@ const imageClass = computed(() => [
|
|
|
116
152
|
:media="media"
|
|
117
153
|
:srcset="srcset"
|
|
118
154
|
>
|
|
119
|
-
<img :src="originalUrl">
|
|
155
|
+
<img :src="originalUrl" :alt="alt">
|
|
120
156
|
</picture>
|
|
121
157
|
</div>
|
|
122
158
|
</template>
|
|
123
159
|
<style lang="scss" scoped>
|
|
124
160
|
.rsui-image {
|
|
125
|
-
@apply w-full h-full flex items-center justify-center
|
|
161
|
+
@apply w-full h-full flex items-center justify-center overflow-hidden;
|
|
126
162
|
&--rounded {
|
|
127
163
|
@apply rounded-lg;
|
|
128
164
|
}
|
|
165
|
+
&--error {
|
|
166
|
+
@apply bg-rsui-grey-100;
|
|
167
|
+
}
|
|
168
|
+
&--empty {
|
|
169
|
+
@apply bg-rsui-grey-100;
|
|
170
|
+
}
|
|
129
171
|
&__empty {
|
|
130
172
|
@apply flex items-center justify-center text-rsui-light;
|
|
131
173
|
}
|