22 <img :class =" classes" v-bind =" attrs" />
33</template >
44
5- <script lang="ts">
6- import {computed , defineComponent } from ' vue'
5+ <script setup lang="ts">
6+ // import type {BImgProps} from '@/types/components'
7+ import {computed } from ' vue'
8+
9+ interface BImgProps {
10+ alt? : string
11+ blank? : boolean
12+ blankColor? : string
13+ block? : boolean
14+ center? : boolean
15+ fluid? : boolean
16+ fluidGrow? : boolean
17+ height? : number | string
18+ left? : boolean
19+ right? : boolean
20+ rounded? : boolean | string
21+ sizes? : string | Array <string >
22+ src? : string
23+ srcset? : string | Array <string >
24+ thumbnail? : boolean
25+ width? : number | string
26+ }
27+
28+ const props = withDefaults (defineProps <BImgProps >(), {
29+ alt: undefined ,
30+ blank: false ,
31+ blankColor: ' transparent' ,
32+ block: false ,
33+ center: false ,
34+ fluid: false ,
35+ fluidGrow: false ,
36+ left: false ,
37+ right: false ,
38+ rounded: false ,
39+ thumbnail: false ,
40+ })
741
8- // Blank image with fill template
942const BLANK_TEMPLATE =
1043 ' <svg width="%{w}" height="%{h}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %{w} %{h}" preserveAspectRatio="none">' +
1144 ' <rect width="100%" height="100%" style="fill:%{f};"></rect>' +
1245 ' </svg>'
1346
14- const makeBlankImgSrc = (width : any , height : any , color : string ) => {
47+ const makeBlankImgSrc = (width : any , height : any , color : string ): string => {
1548 const src = encodeURIComponent (
1649 BLANK_TEMPLATE .replace (' %{w}' , String (width ))
1750 .replace (' %{h}' , String (height ))
@@ -20,106 +53,78 @@ const makeBlankImgSrc = (width: any, height: any, color: string) => {
2053 return ` data:image/svg+xml;charset=UTF-8,${src } `
2154}
2255
23- export default defineComponent ({
24- name: ' BImg' ,
25- props: {
26- alt: {type: String , default: undefined },
27- blank: {type: Boolean , default: false },
28- blankColor: {type: String , default: ' transparent' },
29- block: {type: Boolean , default: false },
30- center: {type: Boolean , default: false },
31- fluid: {type: Boolean , default: false },
32- fluidGrow: {type: Boolean , default: false },
33- height: {type: [Number , String ], required: false },
34- left: {type: Boolean , default: false },
35- right: {type: Boolean , default: false },
36- rounded: {type: [Boolean , String ], default: false },
37- sizes: {type: [String , Array ], required: false },
38- src: {type: String , required: false },
39- srcset: {type: [String , Array ], required: false },
40- thumbnail: {type: Boolean , default: false },
41- width: {type: [Number , String ], required: false },
42- },
43- setup(props ) {
44- const attrs = computed (() => {
45- // eslint-disable-next-line prefer-destructuring
46- let src = props .src
47- let width =
48- (typeof props .width === ' number' ? props .width : parseInt (props .width as string , 10 )) ||
49- null
50- let height =
51- (typeof props .height === ' number' ? props .height : parseInt (props .height as string , 10 )) ||
52- null
53-
54- let srcset = ' '
55- if (typeof props .srcset === ' string' )
56- srcset = props .srcset
57- .split (' ,' )
58- .filter ((x ) => x )
59- .join (' ,' )
60- else if (Array .isArray (props .srcset )) srcset = props .srcset .filter ((x ) => x ).join (' ,' )
56+ const attrs = computed (() => {
57+ // eslint-disable-next-line prefer-destructuring
58+ let src = props .src
59+ let width =
60+ (typeof props .width === ' number' ? props .width : parseInt (props .width as string , 10 )) ||
61+ undefined
62+ let height =
63+ (typeof props .height === ' number' ? props .height : parseInt (props .height as string , 10 )) ||
64+ undefined
6165
62- let sizes = ' '
63- if (typeof props .sizes === ' string' )
64- sizes = props .sizes
65- .split (' ,' )
66- .filter ((x ) => x )
67- .join (' ,' )
68- else if (Array .isArray (props .sizes )) sizes = props .sizes .filter ((x ) => x ).join (' ,' )
66+ let srcset = ' '
67+ if (typeof props .srcset === ' string' )
68+ srcset = props .srcset
69+ .split (' ,' )
70+ .filter ((x ) => x )
71+ .join (' ,' )
72+ else if (Array .isArray (props .srcset )) srcset = props .srcset .filter ((x ) => x ).join (' ,' )
6973
70- if (props .blank ) {
71- if (! height && width ) {
72- height = width
73- } else if (! width && height ) {
74- width = height
75- }
76- if (! width && ! height ) {
77- width = 1
78- height = 1
79- }
80- // Make a blank SVG image
81- src = makeBlankImgSrc (width , height , props .blankColor || ' transparent' )
82- // Disable srcset and sizes
83- srcset = ' '
84- sizes = ' '
85- }
86- return {
87- src ,
88- alt: props .alt ,
89- width: width || null ,
90- height: height || null ,
91- srcset: srcset || null ,
92- sizes: sizes || null ,
93- }
94- })
74+ let sizes = ' '
75+ if (typeof props .sizes === ' string' )
76+ sizes = props .sizes
77+ .split (' ,' )
78+ .filter ((x ) => x )
79+ .join (' ,' )
80+ else if (Array .isArray (props .sizes )) sizes = props .sizes .filter ((x ) => x ).join (' ,' )
9581
96- const classes = computed (() => {
97- let align = ' '
98- // eslint-disable-next-line prefer-destructuring
99- let block = props .block
100- if (props .left ) {
101- align = ' float-start'
102- } else if (props .right ) {
103- align = ' float-end'
104- } else if (props .center ) {
105- align = ' mx-auto'
106- block = true
107- }
108- return {
109- ' img-thumbnail' : props .thumbnail ,
110- ' img-fluid' : props .fluid || props .fluidGrow ,
111- ' w-100' : props .fluidGrow ,
112- ' rounded' : props .rounded === ' ' || props .rounded === true ,
113- [` rounded-${props .rounded } ` ]: typeof props .rounded === ' string' && props .rounded !== ' ' ,
114- [align ]: !! align ,
115- ' d-block' : block ,
116- }
117- })
118-
119- return {
120- attrs ,
121- classes ,
82+ if (props .blank ) {
83+ if (! height && width ) {
84+ height = width
85+ } else if (! width && height ) {
86+ width = height
87+ }
88+ if (! width && ! height ) {
89+ width = 1
90+ height = 1
12291 }
123- },
92+ // Make a blank SVG image
93+ src = makeBlankImgSrc (width , height , props .blankColor || ' transparent' )
94+ // Disable srcset and sizes
95+ srcset = ' '
96+ sizes = ' '
97+ }
98+ return {
99+ src ,
100+ alt: props .alt ,
101+ width: width || undefined ,
102+ height: height || undefined ,
103+ srcset: srcset || undefined ,
104+ sizes: sizes || undefined ,
105+ }
106+ })
107+
108+ const classes = computed (() => {
109+ let align = ' '
110+ // eslint-disable-next-line prefer-destructuring
111+ let block = props .block
112+ if (props .left ) {
113+ align = ' float-start'
114+ } else if (props .right ) {
115+ align = ' float-end'
116+ } else if (props .center ) {
117+ align = ' mx-auto'
118+ block = true
119+ }
120+ return {
121+ ' img-thumbnail' : props .thumbnail ,
122+ ' img-fluid' : props .fluid || props .fluidGrow ,
123+ ' w-100' : props .fluidGrow ,
124+ ' rounded' : props .rounded === ' ' || props .rounded === true ,
125+ [` rounded-${props .rounded } ` ]: typeof props .rounded === ' string' && props .rounded !== ' ' ,
126+ [align ]: !! align ,
127+ ' d-block' : block ,
128+ }
124129})
125130 </script >
0 commit comments