From 176bc652eacd2a24e621e9fb6a67d7fca779231f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E5=90=AF=E7=BC=98?= <1743369777@qq.com>
Date: Thu, 17 Mar 2022 12:21:06 +0800
Subject: [PATCH] refactor(components): [carousel] refactor (#6681)
* refactor(components): [carousel] refactor
* fix: build error
---
internal/build/src/type-safe.json | 1 +
.../{carousel.spec.ts => carousel.spec.tsx} | 203 ++++-----
packages/components/carousel/index.ts | 7 +-
.../components/carousel/src/carousel-item.ts | 15 +
.../components/carousel/src/carousel-item.vue | 169 +++++++
packages/components/carousel/src/carousel.ts | 100 +++--
packages/components/carousel/src/carousel.vue | 324 ++++++++++++++
packages/components/carousel/src/item.vue | 186 --------
packages/components/carousel/src/main.vue | 416 ------------------
packages/tokens/carousel.ts | 35 ++
packages/tokens/index.ts | 1 +
11 files changed, 706 insertions(+), 751 deletions(-)
rename packages/components/carousel/__tests__/{carousel.spec.ts => carousel.spec.tsx} (51%)
create mode 100644 packages/components/carousel/src/carousel-item.ts
create mode 100644 packages/components/carousel/src/carousel-item.vue
create mode 100644 packages/components/carousel/src/carousel.vue
delete mode 100644 packages/components/carousel/src/item.vue
delete mode 100644 packages/components/carousel/src/main.vue
create mode 100644 packages/tokens/carousel.ts
diff --git a/internal/build/src/type-safe.json b/internal/build/src/type-safe.json
index 88fdbd7ddd..f3a89b98ee 100644
--- a/internal/build/src/type-safe.json
+++ b/internal/build/src/type-safe.json
@@ -12,6 +12,7 @@
"packages/components/button/",
"packages/components/button-group/",
"packages/components/card/",
+ "packages/components/carousel/",
"packages/components/check-tag/",
"packages/components/col/",
"packages/components/collapse/",
diff --git a/packages/components/carousel/__tests__/carousel.spec.ts b/packages/components/carousel/__tests__/carousel.spec.tsx
similarity index 51%
rename from packages/components/carousel/__tests__/carousel.spec.ts
rename to packages/components/carousel/__tests__/carousel.spec.tsx
index e193e9e139..170f991720 100644
--- a/packages/components/carousel/__tests__/carousel.spec.ts
+++ b/packages/components/carousel/__tests__/carousel.spec.tsx
@@ -1,46 +1,41 @@
-import { nextTick } from 'vue'
+import { nextTick, reactive } from 'vue'
import { mount } from '@vue/test-utils'
-import Carousel from '../src/main.vue'
-import CarouselItem from '../src/item.vue'
+import Carousel from '../src/carousel.vue'
+import CarouselItem from '../src/carousel-item.vue'
+import type { CarouselInstance } from '../src/carousel'
const wait = (ms = 100) =>
new Promise((resolve) => setTimeout(() => resolve(0), ms))
-const _mount = (template: string, data?: () => void, methods?: any) =>
- mount({
- components: {
- 'el-carousel': Carousel,
- 'el-carousel-item': CarouselItem,
- },
- template,
- data,
- methods,
- })
+const generateCarouselItems = (count = 3) => {
+ const list = Array.from({ length: count }, (_, index) => index + 1)
+ return list.map((i) => )
+}
describe('Carousel', () => {
it('create', () => {
- const wrapper = _mount(
- `
-
-
-
-
-
- `
- )
+ const wrapper = mount({
+ setup() {
+ return () => (
+
+ {generateCarouselItems()}
+
+ )
+ },
+ })
- expect(wrapper.vm.$refs.carousel.direction).toBe('horizontal')
+ const carousel = wrapper.findComponent({ ref: 'carousel' })
+ .vm as CarouselInstance
+ expect(carousel.direction).toBe('horizontal')
expect(wrapper.findAll('.el-carousel__item').length).toEqual(3)
})
it('auto play', async (done) => {
- const wrapper = _mount(`
-
-
-
-
-
- `)
+ const wrapper = mount(() => (
+
+ {generateCarouselItems()}
+
+ ))
await nextTick()
await wait(10)
@@ -52,13 +47,13 @@ describe('Carousel', () => {
})
it('initial index', async (done) => {
- const wrapper = _mount(`
-
-
-
-
-
- `)
+ const wrapper = mount(() => (
+
+
+ {generateCarouselItems()}
+
+
+ ))
await nextTick()
await wait(10)
@@ -72,13 +67,11 @@ describe('Carousel', () => {
})
it('reset timer', async (done) => {
- const wrapper = _mount(`
-
-
-
-
-
- `)
+ const wrapper = mount(() => (
+
+ {generateCarouselItems()}
+
+ ))
await nextTick()
const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
await wrapper.trigger('mouseenter')
@@ -92,43 +85,45 @@ describe('Carousel', () => {
})
it('change', async (done) => {
- const wrapper = _mount(
- `
-
-
-
-
-
- `,
- () => {
- return {
- val: -1,
- oldVal: -1,
+ const state = reactive({
+ val: -1,
+ oldVal: -1,
+ })
+
+ mount({
+ setup() {
+ const handleChange = (val: number, oldVal: number) => {
+ state.val = val
+ state.oldVal = oldVal
}
+
+ return () => (
+
+
+ {generateCarouselItems()}
+
+
+ )
},
- {
- handleChange(val, oldVal) {
- this.val = val
- this.oldVal = oldVal
- },
- }
- )
+ })
await nextTick()
await wait(50)
- expect(wrapper.vm.val).toBe(1)
- expect(wrapper.vm.oldVal).toBe(0)
+ expect(state.val).toBe(1)
+ expect(state.oldVal).toBe(0)
done()
})
it('label', async (done) => {
- const wrapper = _mount(`
-
-
-
-
-
- `)
+ const wrapper = mount(() => (
+
+
+ {[1, 2, 3].map((i) => (
+
+ ))}
+
+
+ ))
await nextTick()
expect(wrapper.find('.el-carousel__button span').text()).toBe('1')
done()
@@ -136,13 +131,11 @@ describe('Carousel', () => {
describe('manual control', () => {
it('hover', async (done) => {
- const wrapper = _mount(`
+ const wrapper = mount(() => (
-
-
-
+ {generateCarouselItems()}
- `)
+ ))
await nextTick()
await wait()
@@ -159,13 +152,13 @@ describe('Carousel', () => {
})
it('card', async (done) => {
- const wrapper = _mount(`
-
-
-
-
-
- `)
+ const wrapper = mount(() => (
+
+
+ {generateCarouselItems(7)}
+
+
+ ))
await nextTick()
await wait()
const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
@@ -185,27 +178,37 @@ describe('Carousel', () => {
})
it('vertical direction', () => {
- const wrapper = _mount(`
-
-
-
-
-
- `)
+ const wrapper = mount({
+ setup() {
+ return () => (
+
+
+ {generateCarouselItems()}
+
+
+ )
+ },
+ })
const items = wrapper.vm.$el.querySelectorAll('.el-carousel__item')
-
- expect(wrapper.vm.$refs.carousel.direction).toBe('vertical')
+ const carousel = wrapper.findComponent({ ref: 'carousel' })
+ .vm as CarouselInstance
+ expect(carousel.direction).toBe('vertical')
expect(items[0].style.transform.includes('translateY')).toBeTruthy()
})
it('pause auto play on hover', async (done) => {
- const wrapper = _mount(`
-
-
-
-
-
- `)
+ const wrapper = mount(() => (
+
+
+ {generateCarouselItems()}
+
+
+ ))
await nextTick()
await wrapper.find('.el-carousel').trigger('mouseenter')
diff --git a/packages/components/carousel/index.ts b/packages/components/carousel/index.ts
index 38f82e8acd..c377404f77 100644
--- a/packages/components/carousel/index.ts
+++ b/packages/components/carousel/index.ts
@@ -1,6 +1,6 @@
import { withInstall, withNoopInstall } from '@element-plus/utils'
-import Carousel from './src/main.vue'
-import CarouselItem from './src/item.vue'
+import Carousel from './src/carousel.vue'
+import CarouselItem from './src/carousel-item.vue'
export const ElCarousel = withInstall(Carousel, {
CarouselItem,
@@ -9,3 +9,6 @@ export const ElCarousel = withInstall(Carousel, {
export default ElCarousel
export const ElCarouselItem = withNoopInstall(CarouselItem)
+
+export * from './src/carousel'
+export * from './src/carousel-item'
diff --git a/packages/components/carousel/src/carousel-item.ts b/packages/components/carousel/src/carousel-item.ts
new file mode 100644
index 0000000000..00426004dd
--- /dev/null
+++ b/packages/components/carousel/src/carousel-item.ts
@@ -0,0 +1,15 @@
+import { buildProps } from '@element-plus/utils'
+import type { ExtractPropTypes } from 'vue'
+import type CarouselItem from './carousel-item.vue'
+
+export const carouselItemProps = buildProps({
+ name: { type: String, default: '' },
+ label: {
+ type: [String, Number],
+ default: '',
+ },
+} as const)
+
+export type CarouselItemProps = ExtractPropTypes
+
+export type CarouselItemInstance = InstanceType
diff --git a/packages/components/carousel/src/carousel-item.vue b/packages/components/carousel/src/carousel-item.vue
new file mode 100644
index 0000000000..622cd06dda
--- /dev/null
+++ b/packages/components/carousel/src/carousel-item.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
diff --git a/packages/components/carousel/src/carousel.ts b/packages/components/carousel/src/carousel.ts
index c96cac3bf1..52ef09b692 100644
--- a/packages/components/carousel/src/carousel.ts
+++ b/packages/components/carousel/src/carousel.ts
@@ -1,51 +1,57 @@
-import type { Ref, ToRefs, UnwrapRef } from 'vue'
+import { buildProps, isNumber } from '@element-plus/utils'
+import type { ExtractPropTypes } from 'vue'
+import type Carousel from './carousel.vue'
-export interface ICarouselItemProps {
- name: string
- label: string | number
- key: string
+export const carouselProps = buildProps({
+ initialIndex: {
+ type: Number,
+ default: 0,
+ },
+ height: { type: String, default: '' },
+ trigger: {
+ type: String,
+ default: 'hover',
+ },
+ autoplay: {
+ type: Boolean,
+ default: true,
+ },
+ interval: {
+ type: Number,
+ default: 3000,
+ },
+ indicatorPosition: { type: String, default: '' },
+ indicator: {
+ type: Boolean,
+ default: true,
+ },
+ arrow: {
+ type: String,
+ default: 'hover',
+ },
+ type: { type: String, default: '' },
+ loop: {
+ type: Boolean,
+ default: true,
+ },
+ direction: {
+ type: String,
+ default: 'horizontal',
+ validator(val: string) {
+ return ['horizontal', 'vertical'].includes(val)
+ },
+ },
+ pauseOnHover: {
+ type: Boolean,
+ default: true,
+ },
+} as const)
+
+export const carouselEmits = {
+ change: (current: number, prev: number) => [current, prev].every(isNumber),
}
-export interface ICarouselItemData {
- hover: boolean
- translate: number
- scale: number
- active: boolean
- ready: boolean
- inStage: boolean
- animating: boolean
-}
+export type CarouselProps = ExtractPropTypes
+export type CarouselEmits = typeof carouselEmits
-export interface ICarouselProps {
- initialIndex: number
- height: string
- trigger: string
- autoplay: boolean
- interval: number
- indicatorPosition: string
- indicator: boolean
- arrow: string
- type: string
- loop: boolean
- direction: string
- pauseOnHover: boolean
-}
-
-export type UnionCarouselItemData = ICarouselItemProps &
- ToRefs
-
-export interface CarouselItem extends UnionCarouselItemData {
- uid: number
- translateItem: (index: number, activeIndex: number, oldIndex: number) => void
-}
-
-export interface InjectCarouselScope {
- root: Ref
- direction: string
- type: string
- items: Ref>
- loop: boolean
- addItem: (item: CarouselItem) => void
- removeItem: (uid: number) => void
- setActiveItem: (index: number) => void
-}
+export type CarouselInstance = InstanceType
diff --git a/packages/components/carousel/src/carousel.vue b/packages/components/carousel/src/carousel.vue
new file mode 100644
index 0000000000..a51833d9d3
--- /dev/null
+++ b/packages/components/carousel/src/carousel.vue
@@ -0,0 +1,324 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/packages/components/carousel/src/item.vue b/packages/components/carousel/src/item.vue
deleted file mode 100644
index e232d749c0..0000000000
--- a/packages/components/carousel/src/item.vue
+++ /dev/null
@@ -1,186 +0,0 @@
-
-
-
-
diff --git a/packages/components/carousel/src/main.vue b/packages/components/carousel/src/main.vue
deleted file mode 100644
index ba74f9643b..0000000000
--- a/packages/components/carousel/src/main.vue
+++ /dev/null
@@ -1,416 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
diff --git a/packages/tokens/carousel.ts b/packages/tokens/carousel.ts
new file mode 100644
index 0000000000..c711c33bc4
--- /dev/null
+++ b/packages/tokens/carousel.ts
@@ -0,0 +1,35 @@
+import type { InjectionKey, Ref, ToRefs, UnwrapRef } from 'vue'
+
+import type { CarouselItemProps } from '@element-plus/components/carousel'
+
+export type CarouselItemContext = CarouselItemProps &
+ ToRefs<{
+ hover: boolean
+ translate: number
+ scale: number
+ active: boolean
+ ready: boolean
+ inStage: boolean
+ animating: boolean
+ }> & {
+ uid: number | undefined
+ translateItem: (
+ index: number,
+ activeIndex: number,
+ oldIndex: number
+ ) => void
+ }
+
+export type CarouselContext = {
+ root: Ref
+ direction: string
+ type: string
+ items: Ref>
+ loop: boolean
+ addItem: (item: CarouselItemContext) => void
+ removeItem: (uid: number | undefined) => void
+ setActiveItem: (index: number) => void
+}
+
+export const carouselContextKey: InjectionKey =
+ Symbol('carouselContextKey')
diff --git a/packages/tokens/index.ts b/packages/tokens/index.ts
index 2d5209b5a8..2a11a2e90d 100644
--- a/packages/tokens/index.ts
+++ b/packages/tokens/index.ts
@@ -1,5 +1,6 @@
export * from './breadcrumb'
export * from './button'
+export * from './carousel'
export * from './collapse'
export * from './config-provider'
export * from './dialog'