Skip to content

Commit 2ed028d

Browse files
author
issayah
committed
BCarousel script setup conversion and improvements
1 parent a3a060d commit 2ed028d

File tree

2 files changed

+111
-108
lines changed

2 files changed

+111
-108
lines changed

src/components/BCarousel/BCarousel.vue

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -40,67 +40,72 @@
4040
</div>
4141
</template>
4242

43-
<script lang="ts">
44-
import {defineComponent, InjectionKey, onMounted, provide, ref, VNode} from 'vue'
43+
<script setup lang="ts">
44+
// import type {BCarouselProps, BCarouselEmits} from '@/types/components'
45+
import type {BCarouselParentData} from '@/types/components'
46+
import {InjectionKey, onMounted, provide, ref, useSlots, VNode} from 'vue'
4547
import Carousel from 'bootstrap/js/dist/carousel'
4648
import useEventListener from '../../composables/useEventListener'
4749
import useId from '../../composables/useId'
4850
49-
export interface ParentData {
51+
interface BCarouselProps {
52+
id: string
53+
imgHeight: string
54+
imgWidth: string
5055
background?: string
51-
width?: string
52-
height?: string
56+
modelValue?: number
57+
controls?: boolean
58+
indicators?: boolean
59+
interval?: number
60+
noTouch?: boolean
61+
noWrap?: boolean
5362
}
5463
55-
export const injectionKey: InjectionKey<ParentData> = Symbol()
64+
const props = withDefaults(defineProps<BCarouselProps>(), {
65+
modelValue: 0,
66+
controls: false,
67+
indicators: false,
68+
interval: 5000,
69+
noTouch: false,
70+
noWrap: false,
71+
})
5672
57-
export default defineComponent({
58-
name: 'BCarousel',
59-
props: {
60-
background: {type: String, required: false},
61-
modelValue: {type: Number, default: 0},
62-
controls: {type: Boolean, default: false},
63-
id: {type: String},
64-
imgHeight: {type: String},
65-
imgWidth: {type: String},
66-
indicators: {type: Boolean, default: false},
67-
interval: {type: Number, default: 5000},
68-
noTouch: {type: Boolean, default: false},
69-
noWrap: {type: Boolean, default: false},
70-
},
71-
emits: ['sliding-start', 'sliding-end'],
72-
setup(props, {slots, emit}) {
73-
const element = ref<HTMLElement>()
74-
const instance = ref<Carousel>()
75-
const computedId = useId(props.id, 'accordion')
76-
const slides = ref<VNode[]>([])
73+
interface BCarouselEmits {
74+
(e: 'sliding-start', value: Event): void
75+
(e: 'sliding-end', value: Event): void
76+
}
7777
78-
useEventListener(element, 'slide.bs.carousel', (payload) => emit('sliding-start', payload))
79-
useEventListener(element, 'slid.bs.carousel', (payload) => emit('sliding-end', payload))
78+
const emit = defineEmits<BCarouselEmits>()
8079
81-
onMounted(() => {
82-
instance.value = new Carousel(element.value as HTMLElement, {
83-
wrap: !props.noTouch,
84-
interval: props.interval,
85-
touch: !props.noTouch,
86-
})
80+
const slots = useSlots()
8781
88-
if (slots.default) {
89-
slides.value = slots.default().filter((child: any) => child.type?.name === 'BCarouselSlide')
90-
}
91-
})
82+
const element = ref<HTMLElement>()
83+
const instance = ref<Carousel>()
84+
const computedId = useId(props.id, 'accordion')
85+
const slides = ref<VNode[]>([])
9286
93-
provide(injectionKey, {
94-
background: props.background,
95-
width: props.imgWidth,
96-
height: props.imgHeight,
97-
})
87+
useEventListener(element, 'slide.bs.carousel', (payload) => emit('sliding-start', payload))
88+
useEventListener(element, 'slid.bs.carousel', (payload) => emit('sliding-end', payload))
9889
99-
return {
100-
element,
101-
computedId,
102-
slides,
103-
}
104-
},
90+
onMounted(() => {
91+
instance.value = new Carousel(element.value as HTMLElement, {
92+
wrap: !props.noTouch,
93+
interval: props.interval,
94+
touch: !props.noTouch,
95+
})
96+
97+
if (slots.default) {
98+
slides.value = slots.default().filter((child: any) => child.type?.name === 'BCarouselSlide')
99+
}
105100
})
101+
102+
provide(injectionKey, {
103+
background: props.background,
104+
width: props.imgWidth,
105+
height: props.imgHeight,
106+
})
107+
</script>
108+
109+
<script lang="ts">
110+
export const injectionKey: InjectionKey<BCarouselParentData> = Symbol()
106111
</script>
Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<!-- eslint-disable vue/no-v-html -->
12
<template>
23
<div
34
:id="computedId"
@@ -11,8 +12,8 @@
1112
class="d-block w-100"
1213
:alt="imgAlt"
1314
:src="imgSrc"
14-
:width="imgWidth || width"
15-
:height="imgHeight || height"
15+
:width="imgWidth || parentWidth"
16+
:height="imgHeight || parentHeight"
1617
:blank="imgBlank"
1718
:blank-color="imgBlankColor"
1819
/>
@@ -36,65 +37,62 @@
3637
</div>
3738
</template>
3839

39-
<script lang="ts">
40-
import useId from '../../composables/useId'
41-
import {computed, defineComponent, inject} from 'vue'
42-
import {injectionKey, ParentData} from './BCarousel.vue'
40+
<script setup lang="ts">
41+
// import type {BCarouselSlideProps} from '@/types/components'
42+
import useId from '@/composables/useId'
43+
import {computed, inject} from 'vue'
44+
import type {BCarouselParentData} from '@/types/components'
45+
import {injectionKey} from './BCarousel.vue'
4346
44-
export default defineComponent({
45-
name: 'BCarouselSlide',
46-
props: {
47-
active: {type: Boolean, default: false},
48-
background: {type: String, required: false},
49-
caption: {type: String, required: false},
50-
captionHtml: {type: String, required: false},
51-
captionTag: {type: String, default: 'h3'},
52-
contentTag: {type: String, default: 'div'},
53-
contentVisibleUp: {type: String, required: false},
54-
id: {type: String, required: false},
55-
imgAlt: {type: String, required: false},
56-
imgBlank: {type: Boolean, default: false},
57-
imgBlankColor: {type: String, default: 'transparent'},
58-
imgHeight: {type: String},
59-
imgSrc: {type: String},
60-
imgWidth: {type: String},
61-
interval: {type: [String, Number]},
62-
text: {type: String, required: false},
63-
textHtml: {type: String, required: false},
64-
textTag: {type: String, default: 'p'},
65-
},
66-
setup(props) {
67-
const parentData = inject<ParentData>(injectionKey, {})
68-
const computedId = useId(props.id, 'accordion')
69-
const img = computed(() => (props.imgBlank ? props.imgBlank : props.imgSrc))
47+
interface BCarouselSlideProps {
48+
imgSrc: string
49+
imgHeight: string
50+
imgWidth: string
51+
interval: string | number
52+
active?: boolean
53+
background?: string
54+
caption?: string
55+
captionHtml?: string
56+
captionTag?: string
57+
contentTag?: string
58+
contentVisibleUp?: string
59+
id?: string
60+
imgAlt?: string
61+
imgBlank?: boolean
62+
imgBlankColor?: string
63+
text?: string
64+
textHtml?: string
65+
textTag?: string
66+
}
7067
71-
const computedAttr = computed(() => ({
72-
background: `${
73-
props.background || parentData.background || 'rgb(171, 171, 171)'
74-
} none repeat scroll 0% 0%`,
75-
}))
68+
const props = withDefaults(defineProps<BCarouselSlideProps>(), {
69+
active: false,
70+
captionTag: 'h3',
71+
contentTag: 'div',
72+
imgBlank: false,
73+
imgBlankColor: 'transparent',
74+
textTag: 'p',
75+
})
7676
77-
const computedContentClasses = computed(() => ({
78-
'd-none': props.contentVisibleUp,
79-
[`d-${props.contentVisibleUp}-block`]: props.contentVisibleUp,
80-
}))
81-
const showText = computed(() => props.text && !props.textHtml)
82-
const showTextAsHtml = computed(() => props.textHtml)
83-
const showCaption = computed(() => props.caption && !props.captionHtml)
84-
const showCaptionAsHtml = computed(() => props.captionHtml)
77+
const parentData = inject<BCarouselParentData>(injectionKey, {})
78+
const computedId = useId(props.id, 'accordion')
79+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
80+
const img = computed<string | true>(() => (props.imgBlank ? props.imgBlank : props.imgSrc))
8581
86-
return {
87-
computedAttr,
88-
computedContentClasses,
89-
computedId,
90-
height: parentData.height,
91-
img,
92-
showCaption,
93-
showCaptionAsHtml,
94-
showText,
95-
showTextAsHtml,
96-
width: parentData.width,
97-
}
98-
},
99-
})
82+
const computedAttr = computed(() => ({
83+
background: `${
84+
props.background || parentData.background || 'rgb(171, 171, 171)'
85+
} none repeat scroll 0% 0%`,
86+
}))
87+
88+
const computedContentClasses = computed(() => ({
89+
'd-none': props.contentVisibleUp,
90+
[`d-${props.contentVisibleUp}-block`]: props.contentVisibleUp,
91+
}))
92+
const showText = computed<boolean | '' | undefined>(() => props.text && !props.textHtml)
93+
const showTextAsHtml = computed<string | undefined>(() => props.textHtml)
94+
const showCaption = computed<boolean | '' | undefined>(() => props.caption && !props.captionHtml)
95+
const showCaptionAsHtml = computed<string | undefined>(() => props.captionHtml)
96+
const parentWidth = computed<string | undefined>(() => parentData.width)
97+
const parentHeight = computed<string | undefined>(() => parentData.height)
10098
</script>

0 commit comments

Comments
 (0)