diff --git a/src/shared/useClickAway/index.ts b/src/shared/useClickAway/index.ts new file mode 100644 index 000000000..619198b50 --- /dev/null +++ b/src/shared/useClickAway/index.ts @@ -0,0 +1,98 @@ +import { MaybeElementRef, UnRefElementReturn, unrefElement, useEventListener } from '@vueuse/core'; +import { isArray } from 'lodash'; +import { inBrowser } from '../util'; + +export interface UseClickAwayOptions { + /** + * The name of the trigger event. + * @default 'touchstart' + */ + eventName?: string; + /** + * Use capturing phase for internal event listener. + * @default true + */ + capture?: boolean; + /** + * List of elements that should not trigger the event. + */ + ignore?: Array; + /** + * Run handler function if focus moves to an iframe. + * @default false + */ + detectIframe?: boolean; +} + +export type UseClickAwayHandler< + T extends { detectIframe: UseClickAwayOptions['detectIframe'] } = { detectIframe: false }, +> = (evt: T['detectIframe'] extends true ? PointerEvent | FocusEvent : PointerEvent) => void; + +/** + * Listen for clicks outside of a collection of elements. + * @param target + * @param fn + * @param options + */ +export function useClickAway( + target: MaybeElementRef | Array, + fn: UseClickAwayHandler<{ detectIframe: T['detectIframe'] }>, + options: T = {} as T, +) { + if (!inBrowser) return; + + const { eventName = 'touchstart', capture = true, ignore = [], detectIframe = false } = options; + + const listenerOptions = { + passive: true, + capture, + }; + + // el是否包含在event.target + const checkElInEvtTarget = (el: UnRefElementReturn, event: PointerEvent) => { + return el && (event.target === el || event.composedPath().includes(el)); + }; + + const shouldIgnore = (event: PointerEvent) => { + return ignore.some((ignoreTarget) => checkElInEvtTarget(unrefElement(ignoreTarget), event)); + }; + + const eventHandler = (event: PointerEvent) => { + const targets = isArray(target) ? [...target] : [target]; + + let shouldTrigger = targets.every((targetItem) => !checkElInEvtTarget(unrefElement(targetItem), event)); + + if (!shouldTrigger) return; + + shouldTrigger = !shouldIgnore(event); + + if (!shouldTrigger) return; + + fn(event); + }; + + const cleanup = [useEventListener(window, eventName, eventHandler, listenerOptions)]; + + if (detectIframe) { + cleanup.push( + useEventListener(window, 'blur', (event: PointerEvent) => { + setTimeout(() => { + const targets = isArray(target) ? [...target] : [target]; + + if ( + targets.every((targetItem) => { + const el = unrefElement(targetItem); + return ( + window.document.activeElement?.tagName === 'IFRAME' && !el?.contains(window.document.activeElement) + ); + }) + ) { + fn(event); + } + }, 0); + }), + ); + } + + return () => cleanup.forEach((clean) => clean()); +} diff --git a/src/swipe-cell/__test__/__snapshots__/demo.test.jsx.snap b/src/swipe-cell/__test__/__snapshots__/demo.test.jsx.snap index ee67ef0eb..4fe45d2e7 100644 --- a/src/swipe-cell/__test__/__snapshots__/demo.test.jsx.snap +++ b/src/swipe-cell/__test__/__snapshots__/demo.test.jsx.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1 -exports[`SwipeCell > SwipeCell bindVue demo works fine 1`] = ` +exports[`SwipeCell > SwipeCell doubleVue demo works fine 1`] = `
@@ -11,238 +11,88 @@ exports[`SwipeCell > SwipeCell bindVue demo works fine 1`] = `

- 通过expanded实现父子组件联动 + 左右滑操作

-
-
- - -
-
- 开关 - - -
-
- -
-
-
- - -
-
-
- -
- -
- - - -
-
-
- - -
-
- 父子组件联动 - - -
- - + 选择
-
-
- - - - - + +
-
-
- - - -`; - -exports[`SwipeCell > SwipeCell btnsVue demo works fine 1`] = ` -
-
- -

- 左右两侧都有菜单 -

-
-
- -
-
+
- - - - - -
-
- + + +
-
- - -
-
- 左右都有菜单 - - -
+ 左右滑操作
- +
+ 辅助信息 +
+
+
- - - - + 收藏 +
+
+ 删除 +
+
+
+ +
@@ -251,9 +101,10 @@ exports[`SwipeCell > SwipeCell btnsVue demo works fine 1`] = `
`; -exports[`SwipeCell > SwipeCell contentVue demo works fine 1`] = ` +exports[`SwipeCell > SwipeCell eventVue demo works fine 1`] = `
SwipeCell contentVue demo works fine 1`] = `

- 通过直接传入内容或者使用 slot#content 来渲染 + 带二次确认的操作

SwipeCell contentVue demo works fine 1`] = `
- - - -
-
- 直接写组件 + 编辑
- -
-
- -
- +
+ 删除
- - -
-
-
- -
-
-`; - -exports[`SwipeCell > SwipeCell disabledVue demo works fine 1`] = ` -
-
- -

- 是否启用滑动功能 -

-
-
- -
-
- - -
-
- 开关 - - -
-
- -
+
-
- - -
+
-
- -
-
-
-
- - - -
-
-
- - -
-
- 可以滑动 - - -
- -
-
- - - - - - -
-
-
- -
-
-`; - -exports[`SwipeCell > SwipeCell eventVue demo works fine 1`] = ` -
-
- -

- 点击事件 -

-
-
- -
-
-
- - - - - -
-
- -
-
- - -
-
- 左右都有内容 - - -
-
- 辅助信息 -
- -
- -
-
- - - - - - -
-
-
- -
-
-`; - -exports[`SwipeCell > SwipeCell leftCardVue demo works fine 1`] = ` -
- -
-
- -

- 左滑大列表 -

-
-
- -
-
-
- - - -
-
- -
-
-
- - - -
- -
-
- 左滑大列表 - -
- 一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内容文字 -
-
- - -
- -
-
- - - - - -
-
-
- -
-
-
- -
- -
-
-
- - - -
-
- -
-
-
- - - -
- -
-
- 左滑大列表 - -
- 一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内容文字 -
-
- - -
- -
-
- - - - - -
-
-
- -
-
- -
-`; - -exports[`SwipeCell > SwipeCell leftMoreMenuVue demo works fine 1`] = ` -
- -
-
- -

- 左滑多操作 -

-
-
- -
-
-
- - - -
-
- -
-
- - -
-
- 列表-左滑双操作 - - -
-
- 多操作 -
- -
- -
-
- - - - - - - -
-
-
- -
-
-
- -
- -
-
-
- - - -
-
- -
-
- - -
-
- 列表-左滑双操作 - - -
-
- 多操作 -
- -
- -
-
- - - - - - - -
-
-
- -
-
- -
-`; - -exports[`SwipeCell > SwipeCell leftOneMenuVue demo works fine 1`] = ` -
- -
-
- -

- 左滑单操作 -

-
-
- -
-
-
- - - -
-
- -
-
- - -
-
- 列表-左滑单操作 - - -
-
- 辅助信息 -
- -
- -
-
- - - - - +
+ 带二次确认的操作 + +
+
+ 辅助信息 +
+
-
- -
-
-
- -
- -
+
+
- - - + 编辑
- -
-
- - -
-
- 列表-左滑单操作 - - -
-
- 辅助信息 -
- -
- + 删除
+
+
- - - - - +
-
+
-
`; -exports[`SwipeCell > SwipeCell leftTwoMenuVue demo works fine 1`] = ` +exports[`SwipeCell > SwipeCell iconVue demo works fine 1`] = `
@@ -1257,7 +229,7 @@ exports[`SwipeCell > SwipeCell leftTwoMenuVue demo works fine 1`] = `

- 左滑双操作 + 带图标的滑动操作

SwipeCell leftTwoMenuVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
-
- - -
-
- 列表-左滑双操作 - - -
-
- 双操作 -
+
- +
+ 图标加文字横排 + + +
+
+ 辅助信息 +
+
+
- - - - +
+
+
+ +
@@ -1358,7 +361,6 @@ exports[`SwipeCell > SwipeCell leftTwoMenuVue demo works fine 1`] = `
SwipeCell leftTwoMenuVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
-
- - -
-
- 列表-左滑双操作 - - -
-
- 双操作 -
+
- +
+ 纯图标 + + +
+
+ 辅助信息 +
+
+
- - - -
+
- - - - 删除 - - - - - -
-
-
- -
-
- -
-`; - -exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` -
-

- SwipeCell 滑动单元格 -

-

- 用来承载列表中的更多操作,通过左右滑动来展示,按钮的宽度固定高度根据列表高度而变化。 -

- -
-
- -

- 左滑单操作 -

-
-
- -
-
-
- - - -
-
+ + + + + +
+
-
- - -
-
- 列表-左滑单操作 - - -
-
- 辅助信息 -
- -
-
- - - - -
@@ -1569,7 +482,6 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `
SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
+ + +
+
+ 图标加文字竖排 +
- - -
-
- 列表-左滑单操作 - - -
-
- 辅助信息 + 一段很长很长的内容文字
-
- +
+ 辅助信息 +
+
+
-
+
- + + + + - 删除 - - - - - +
+
+
+ +
@@ -1651,18 +616,29 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `
+
+`; + +exports[`SwipeCell > SwipeCell leftVue demo works fine 1`] = ` +
- +

+ 组件类型 +

- 左滑双操作 + 左滑动操作

SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
-
- - -
-
- 列表-左滑双操作 - - -
-
- 双操作 -
+
- +
+ 左滑单操作 + + +
+
+ 辅助信息 +
+
+
- - - - + 删除 +
+
+
+ +
@@ -1774,109 +729,82 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
+ + +
+
+ 左滑单操作 +
- - -
-
- 列表-左滑双操作 - - -
-
- 双操作 + 一段很长很长的内容文字
-
- +
+ 辅助信息 +
+
+
- - - - + 删除 +
+
+
+ +
- -
-
- -

- 左滑多操作 -

-
+
@@ -1885,105 +813,84 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
-
- - -
-
- 列表-左滑双操作 - - -
-
- 多操作 -
+
- +
+ 左滑双操作 + + +
+
+ 辅助信息 +
+
+
- - - - - +
+
+
+ +
@@ -2003,105 +910,95 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
-
- - -
-
- 列表-左滑双操作 - - -
-
- 多操作 -
+
- +
+ 左滑三操作 + + +
+
+ 辅助信息 +
+
+
- - - - - +
+
+
+ +
@@ -2109,18 +1006,39 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `
+
+`; + +exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` +
+

+ Swipecell 滑动操作 +

+

+ 用于承载列表中的更多操作,通过左右滑动来展示,按钮的宽度固定高度根据列表高度而变化。 +

- +

+ 组件类型 +

- 左滑大列表 + 左滑动操作

SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
-
-
- - - -
- -
-
- 左滑大列表 - -
- 一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内容文字 -
-
- +
+ 左滑单操作 + + +
+
+ 辅助信息 +
+
+
- - - + 删除 +
+
+
+ +
@@ -2223,100 +1129,82 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+
+ +
+
-
+ + +
+
+ 左滑单操作 +
-
- - - -
- -
-
- 左滑大列表 - -
- 一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内容文字 -
+ 一段很长很长的内容文字
- -
- +
+ 辅助信息 +
+
+
- - - + 删除 +
+
+
+ +
- -
-
- -

- 右滑单操作 -

-
+
@@ -2325,70 +1213,84 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- - - +
+
+ +
+
-
+ + +
+
-
- - -
-
- 列表-右滑单操作 - - -
-
- 辅助信息 -
+ 左滑双操作 +
- +
+ 辅助信息 +
+
+
- +
+ + + 编辑 + +
+
+ + + 删除 + +
+
+
+ +
@@ -2408,70 +1310,95 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
+ + +
+
+ +
+
+ +
+
+ + +
+
+ 左滑三操作 + + +
+
+ 辅助信息 +
+ +
+ +
-
+
+ + + 编辑 + +
+
- + - - 选择 - + 删除 - - - - - -
-
+
+
-
- - -
-
- 列表-右滑单操作 - - -
-
- 辅助信息 -
- -
-
- - -
@@ -2489,115 +1416,78 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `

- 通过expanded实现父子组件联动 + 右滑动操作

-
-
- - -
-
- 开关 - - -
-
- -
-
-
- - -
-
-
- -
- -
- +
+ 选择 +
+
+
+ +
+
-
-
- - -
-
- 父子组件联动 - - -
- +
+ 右滑单操作 + + +
+
+ 辅助信息 +
+
+
- - - +
+
+ +
@@ -2614,7 +1504,7 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `

- 通过直接传入内容或者使用 slot#content 来渲染 + 左右滑操作

SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- +
+ 选择 +
+
+
+ +
+
-
- 直接写组件 + +
- +
+ 左右滑操作 + + +
+
+ 辅助信息 +
+
+
-
- +
+ 收藏 +
+
+ 删除
- - +
+
+ +
+
@@ -2690,133 +1603,130 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `

- 是否启用滑动功能 + 带图标的滑动操作

-
-
- - -
-
- 开关 - - -
-
- -
-
-
- - -
-
-
- -
- -
- +
+
+ +
+
-
-
- - -
-
- 可以滑动 - - -
- +
+ 图标加文字横排 + + +
+
+ 辅助信息 +
+
+
- - - - +
+
+
+ +
@@ -2826,16 +1736,7 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `
-
- -

- 左右两侧都有菜单 -

-
+
@@ -2844,99 +1745,109 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- - - +
+
+ +
+
-
+ + +
+
-
- - -
-
- 左右都有菜单 - - -
+ 纯图标
- +
+ 辅助信息 +
+
+
- - - - + + + + + + +
+
+ + + + + +
+
+
+ +
@@ -2946,16 +1857,7 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = `
-
- -

- 点击事件 -

-
+
@@ -2964,121 +1866,133 @@ exports[`SwipeCell > SwipeCell mobileVue demo works fine 1`] = ` class="t-swipe-cell" >
- - - +
+
+ +
+
-
+ + +
+
+ 图标加文字竖排 +
- - -
-
- 左右都有内容 - - -
-
- 辅助信息 + 一段很长很长的内容文字
-
- +
+ 辅助信息 +
+
+
- - - - +
+
+
+ +
-
-`; - -exports[`SwipeCell > SwipeCell rightMenuVue demo works fine 1`] = ` -
SwipeCell rightMenuVue demo works fine 1`] = `

- 右滑单操作 + 带二次确认的操作

SwipeCell rightMenuVue demo works fine 1`] = `
- - - + 编辑 +
+
+ 删除 +
+
+
+ +
+
-
-
- - -
-
- 列表-右滑单操作 - - -
-
- 辅助信息 -
+
- +
+ 带二次确认的操作 + + +
+
+ 辅助信息 +
+
+
- +
+ 编辑 +
+
+ 删除 +
+
+
+ +
+
+`; + +exports[`SwipeCell > SwipeCell rightVue demo works fine 1`] = ` +
+

+ 右滑动操作 +

+
+
+
-
+ +
+ 选择 +
+ +
+
+ +
+
+ +
- - - - - + +
- -
-
- - -
-
- 列表-右滑单操作 - - -
-
- 辅助信息 -
- -
- + 右滑单操作 + +
- - - + 辅助信息 +
+ +
+ +
+ + +
+
+
-
+
-
`; diff --git a/src/swipe-cell/__test__/demo.test.jsx b/src/swipe-cell/__test__/demo.test.jsx index 076a44dc0..3ef78673a 100644 --- a/src/swipe-cell/__test__/demo.test.jsx +++ b/src/swipe-cell/__test__/demo.test.jsx @@ -3,30 +3,20 @@ */ import { mount } from '@vue/test-utils'; -import bindVue from '@/swipe-cell/demos/bind.vue'; -import btnsVue from '@/swipe-cell/demos/btns.vue'; -import contentVue from '@/swipe-cell/demos/content.vue'; -import disabledVue from '@/swipe-cell/demos/disabled.vue'; +import doubleVue from '@/swipe-cell/demos/double.vue'; import eventVue from '@/swipe-cell/demos/event.vue'; -import leftCardVue from '@/swipe-cell/demos/left-card.vue'; -import leftMoreMenuVue from '@/swipe-cell/demos/left-more-menu.vue'; -import leftOneMenuVue from '@/swipe-cell/demos/left-one-menu.vue'; -import leftTwoMenuVue from '@/swipe-cell/demos/left-two-menu.vue'; +import iconVue from '@/swipe-cell/demos/icon.vue'; +import leftVue from '@/swipe-cell/demos/left.vue'; import mobileVue from '@/swipe-cell/demos/mobile.vue'; -import rightMenuVue from '@/swipe-cell/demos/right-menu.vue'; +import rightVue from '@/swipe-cell/demos/right.vue'; const mapper = { - bindVue, - btnsVue, - contentVue, - disabledVue, + doubleVue, eventVue, - leftCardVue, - leftMoreMenuVue, - leftOneMenuVue, - leftTwoMenuVue, + iconVue, + leftVue, mobileVue, - rightMenuVue, + rightVue, }; describe('SwipeCell', () => { diff --git a/src/swipe-cell/__test__/index.test.jsx b/src/swipe-cell/__test__/index.test.jsx index 107999191..cb772eb28 100644 --- a/src/swipe-cell/__test__/index.test.jsx +++ b/src/swipe-cell/__test__/index.test.jsx @@ -5,10 +5,10 @@ import Button from '../../button/button.vue'; import { AppIcon as TIconApp } from 'tdesign-icons-vue-next'; import { trigger } from '../../image-viewer/__test__/touch'; -const move = async (target) => { - await trigger(target, 'touchstart', 0, 0); - await trigger(target, 'touchmove', 120, 0); - await trigger(target, 'touchend', 120, 0); +const move = async (target, offset = 120, start = 0) => { + await trigger(target, 'touchstart', start, 0); + await trigger(target, 'touchmove', start + offset, 0); + return async () => await trigger(target, 'touchend', start + offset, 0); }; describe('swipe-cell', () => { @@ -20,27 +20,33 @@ describe('swipe-cell', () => { { text: '编辑', className: 't-button--primary', onClick: handleEdit }, { text: '删除', className: 't-button--danger', onClick: handleDelete }, ]; - const expanded = 'right'; const content = 'content is a string'; - const wrapper = mount(); + const wrapper = mount(
{content}
} right={right} />); // expect(wrapper).toMatchSnapshot() // content - const $content = wrapper.find('.t-swipe-cell__content'); + const $content = wrapper.find('.swipe-cell__content'); expect($content.text()).toBe(content); // right: - const $right = wrapper.find('.t-swipe-cell__right'); - const $buttons = wrapper.findAllComponents(Button); + const $right = wrapper.findAll('.t-swipe-cell__right'); + const $buttons = wrapper.findAll('.t-swipe-cell__content'); + console.log($buttons.length, right.length) expect($buttons).toHaveLength(right.length); right.forEach((item, index) => { - expect($buttons.at(index).text()).toBe(right[index].text); + expect($buttons.at(index).find('.t-swipe-cell__text').text()).toBe(right[index].text); }); + wrapper.vm.initData.rightWidth = 120; + await wrapper.setProps({ opened: true }); // handleEdit wrapper.find(`.${right[0].className}`).trigger('click'); expect(handleEdit).toHaveBeenCalledTimes(1); + + await wrapper.setProps({ opened: false }); + wrapper.vm.initData.rightWidth = 120; + await wrapper.setProps({ opened: true }); // handleDelete wrapper.find(`.${right[1].className}`).trigger('click'); expect(handleDelete).toHaveBeenCalledTimes(1); @@ -61,25 +67,31 @@ describe('swipe-cell', () => { }, }); - wrapper.vm.initData.leftWidth = 40; - wrapper.vm.initData.status = 'open'; - await wrapper.setProps({ expanded: 'left' }); + wrapper.vm.initData.leftWidth = 60; + await wrapper.setProps({ opened: true }); + expect(onChange).toBeCalledTimes(1); + expect(onChange).toHaveBeenCalledWith('left'); - const $buttons = wrapper.findAllComponents(Button); + const $buttons = wrapper.findAll('.t-swipe-cell__content'); $buttons.at(0).trigger('click'); expect(onClick).toBeCalledTimes(1); - expect(onChange).toBeCalledTimes(1); + expect(onChange).toBeCalledTimes(2); expect(onChange).toHaveBeenCalledWith(undefined); const $target = wrapper.find('.t-swipe-cell__content'); // disabled = true, 滑动操作无效 await wrapper.setProps({ disabled: true }); - move($target); + let touchend = await move($target); + expect(wrapper.vm.initData.moving).toBe(false); + touchend(); + expect(wrapper.vm.initData.moving).toBe(false); // disabled = false, 开启滑动操作 await wrapper.setProps({ disabled: false }); - move($target); + touchend = await move($target); expect(wrapper.vm.initData.moving).toBe(true); + touchend(); + expect(wrapper.vm.initData.moving).toBe(false); }); it(': right', async () => { @@ -100,23 +112,38 @@ describe('swipe-cell', () => { }, }); - wrapper.vm.initData.rightWidth = 40; - await wrapper.setProps({ expanded: 'right' }); + wrapper.vm.initData.rightWidth = 120; + await wrapper.setProps({ opened: true }); expect(onChange).toBeCalledTimes(1); expect(onChange).toHaveBeenCalledWith('right'); - const $buttons = wrapper.findAllComponents(Button); + const $buttons = wrapper.findAll('.t-swipe-cell__content'); $buttons.at(0).trigger('click'); expect(onClick).toBeCalledTimes(1); + expect(onChange).toBeCalledTimes(2); + expect(onChange).toHaveBeenCalledWith(undefined); + + await wrapper.setProps({ opened: false }); + wrapper.vm.initData.rightWidth = 120; + await wrapper.setProps({ opened: true }); + expect(onChange).toBeCalledTimes(3); + expect(onChange).toHaveBeenCalledWith('right'); $buttons.at(1).trigger('click'); expect(onClick).toBeCalledTimes(2); - expect(onChange).toBeCalledTimes(2); + expect(onChange).toBeCalledTimes(4); expect(onChange).toHaveBeenCalledWith(undefined); const $target = wrapper.find('.t-swipe-cell__content'); - move($target); + let touchend = await move($target, 9); + expect(wrapper.vm.initData.moving).toBe(false); + await touchend(); + expect(wrapper.vm.initData.moving).toBe(false); + + touchend = await move($target); expect(wrapper.vm.initData.moving).toBe(true); + await touchend(); + expect(wrapper.vm.initData.moving).toBe(false); }); }); @@ -128,7 +155,7 @@ describe('swipe-cell', () => { content: icon, }, }); - const $content = wrapper.find('.t-swipe-cell__content'); + const $content = wrapper; expect($content.findComponent(TIconApp).exists()).toBeTruthy(); }); }); diff --git a/src/swipe-cell/demos/bind.vue b/src/swipe-cell/demos/bind.vue deleted file mode 100644 index 297fe97d7..000000000 --- a/src/swipe-cell/demos/bind.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/btns.vue b/src/swipe-cell/demos/btns.vue deleted file mode 100644 index 203d9f1ab..000000000 --- a/src/swipe-cell/demos/btns.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/content.vue b/src/swipe-cell/demos/content.vue deleted file mode 100644 index 33a5027ad..000000000 --- a/src/swipe-cell/demos/content.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/disabled.vue b/src/swipe-cell/demos/disabled.vue deleted file mode 100644 index 4d72e72f9..000000000 --- a/src/swipe-cell/demos/disabled.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/double.vue b/src/swipe-cell/demos/double.vue new file mode 100644 index 000000000..2e2d2a072 --- /dev/null +++ b/src/swipe-cell/demos/double.vue @@ -0,0 +1,25 @@ + + + diff --git a/src/swipe-cell/demos/event.vue b/src/swipe-cell/demos/event.vue index 99d34ade3..4e5b03135 100644 --- a/src/swipe-cell/demos/event.vue +++ b/src/swipe-cell/demos/event.vue @@ -1,35 +1,64 @@ + + diff --git a/src/swipe-cell/demos/icon.vue b/src/swipe-cell/demos/icon.vue new file mode 100644 index 000000000..9a2e1b94c --- /dev/null +++ b/src/swipe-cell/demos/icon.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/swipe-cell/demos/left-card.vue b/src/swipe-cell/demos/left-card.vue deleted file mode 100644 index f4d6d5b16..000000000 --- a/src/swipe-cell/demos/left-card.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/left-more-menu.vue b/src/swipe-cell/demos/left-more-menu.vue deleted file mode 100644 index 2eae8bf85..000000000 --- a/src/swipe-cell/demos/left-more-menu.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/left-one-menu.vue b/src/swipe-cell/demos/left-one-menu.vue deleted file mode 100644 index 719682652..000000000 --- a/src/swipe-cell/demos/left-one-menu.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/left-two-menu.vue b/src/swipe-cell/demos/left-two-menu.vue deleted file mode 100644 index 4c3a55b08..000000000 --- a/src/swipe-cell/demos/left-two-menu.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/left.vue b/src/swipe-cell/demos/left.vue new file mode 100644 index 000000000..0314851eb --- /dev/null +++ b/src/swipe-cell/demos/left.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/src/swipe-cell/demos/mobile.vue b/src/swipe-cell/demos/mobile.vue index 21aac4707..febed9345 100644 --- a/src/swipe-cell/demos/mobile.vue +++ b/src/swipe-cell/demos/mobile.vue @@ -1,29 +1,19 @@ diff --git a/src/swipe-cell/demos/right-menu.vue b/src/swipe-cell/demos/right-menu.vue deleted file mode 100644 index f68a82097..000000000 --- a/src/swipe-cell/demos/right-menu.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/src/swipe-cell/demos/right.vue b/src/swipe-cell/demos/right.vue new file mode 100644 index 000000000..89e7ec8ad --- /dev/null +++ b/src/swipe-cell/demos/right.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/swipe-cell/props.ts b/src/swipe-cell/props.ts index 4d977cfda..3a76f92d0 100644 --- a/src/swipe-cell/props.ts +++ b/src/swipe-cell/props.ts @@ -12,23 +12,21 @@ export default { content: { type: [String, Function] as PropType, }, - /** 子内容,同 content */ + /** 操作项以外的内容,同 content */ default: { type: [String, Function] as PropType, }, /** 是否禁用滑动 */ disabled: Boolean, - /** 操作项是否呈现为打开态 */ - expanded: { - type: String as PropType, - validator(val: TdSwipeCellProps['expanded']): boolean { - return ['left', 'right'].includes(val!); - }, - }, /** 左侧滑动操作项。所有行为同 `right` */ left: { type: [Array, Function] as PropType, }, + /** 操作项是否呈现为打开态,值为数组时表示分别控制左右滑动的展开和收起状态 */ + opened: { + type: [Boolean, Array] as PropType, + default: false, + }, /** 右侧滑动操作项。有两种定义方式,一种是使用数组,二种是使用插槽。`right.text` 表示操作文本,`right.className` 表示操作项类名,`right.style` 表示操作项样式,`right.onClick` 表示点击操作项后执行的回调函数。示例:`[{ text: '删除', style: 'background-color: red', onClick: () => {} }]` */ right: { type: [Array, Function] as PropType, diff --git a/src/swipe-cell/style/index.js b/src/swipe-cell/style/index.js index f23b5f99b..b17ce5ec8 100644 --- a/src/swipe-cell/style/index.js +++ b/src/swipe-cell/style/index.js @@ -1 +1 @@ -import '../../_common/style/mobile/components/swipe-cell/_index.less'; +import '../../_common/style/mobile/components/swipe-cell/v2/_index.less'; diff --git a/src/swipe-cell/swipe-cell.en-US.md b/src/swipe-cell/swipe-cell.en-US.md new file mode 100644 index 000000000..e4d07129b --- /dev/null +++ b/src/swipe-cell/swipe-cell.en-US.md @@ -0,0 +1,29 @@ +:: BASE_DOC :: + +## API + +### SwipeCell Props + +name | type | default | description | required +-- | -- | -- | -- | -- +content | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N +default | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N +disabled | Boolean | - | \- | N +left | Array / Slot / Function | - | Typescript:`Array` | N +opened | Boolean / Array | false | Typescript:`boolean \| Array` | N +right | Array / Slot / Function | - | Typescript:`Array` `interface SwipeActionItem {text: string; className?: string; style?: string; onClick?: () => void; [key: string]: any }`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts) | N +onChange | Function | | Typescript:`(value: string) => void`
| N +onClick | Function | | Typescript:`(action: SwipeActionItem, source: SwipeSource) => void`
[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
`type SwipeSource = 'left' \| 'right'`
| N + +### SwipeCell Events + +name | params | description +-- | -- | -- +change | `(value: string)` | \- +click | `(action: SwipeActionItem, source: SwipeSource)` | [see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
`type SwipeSource = 'left' \| 'right'`
+ +### SwipeCellInstanceFunctions + +名称 | 参数 | 返回值 | 描述 +-- | -- | -- | -- +showSure | `(sure: string | TNode, onClick?: SwipeActionItem['onClick'])` | `void` | [see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
diff --git a/src/swipe-cell/swipe-cell.md b/src/swipe-cell/swipe-cell.md index 38b5b9358..afff35515 100644 --- a/src/swipe-cell/swipe-cell.md +++ b/src/swipe-cell/swipe-cell.md @@ -5,18 +5,24 @@ 名称 | 类型 | 默认值 | 说明 | 必传 -- | -- | -- | -- | -- -content | String / Slot / Function | - | 操作项以外的内容。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N -default | String / Slot / Function | - | 子内容,同 content。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N +content | String / Slot / Function | - | 操作项以外的内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N +default | String / Slot / Function | - | 操作项以外的内容,同 content。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N disabled | Boolean | - | 是否禁用滑动 | N -expanded | String | - | 操作项是否呈现为打开态。可选项:left/right | N left | Array / Slot / Function | - | 左侧滑动操作项。所有行为同 `right`。TS 类型:`Array` | N -right | Array / Slot / Function | - | 右侧滑动操作项。有两种定义方式,一种是使用数组,二种是使用插槽。`right.text` 表示操作文本,`right.className` 表示操作项类名,`right.style` 表示操作项样式,`right.onClick` 表示点击操作项后执行的回调函数。示例:`[{ text: '删除', style: 'background-color: red', onClick: () => {} }]`。TS 类型:`Array` `interface SwipeActionItem { theme: string, text: string; className?: string; style?: string; onClick?: () => void; [key: string]: any }`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts) | N +opened | Boolean / Array | false | 操作项是否呈现为打开态,值为数组时表示分别控制左右滑动的展开和收起状态。TS 类型:`boolean \| Array` | N +right | Array / Slot / Function | - | 右侧滑动操作项。有两种定义方式,一种是使用数组,二种是使用插槽。`right.text` 表示操作文本,`right.className` 表示操作项类名,`right.style` 表示操作项样式,`right.onClick` 表示点击操作项后执行的回调函数。示例:`[{ text: '删除', style: 'background-color: red', onClick: () => {} }]`。TS 类型:`Array` `interface SwipeActionItem {text: string; className?: string; style?: string; onClick?: () => void; [key: string]: any }`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts) | N onChange | Function | | TS 类型:`(value: string) => void`
菜单展开或者收回后将菜单的状态传递给父组件,值为数组时表示分别控制左右滑动的展开和收起状态。 | N -onClick | Function | | TS 类型:`(context: SwipeActionClickContext) => void`
操作项点击时触发(插槽写法组件不触发,业务侧自定义内容和事件)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
`interface SwipeActionClickContext { action: SwipeActionItem; source: 'left' | 'right' }`
| N +onClick | Function | | TS 类型:`(action: SwipeActionItem, source: SwipeSource) => void`
操作项点击时触发(插槽写法组件不触发,业务侧自定义内容和事件)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
`type SwipeSource = 'left' \| 'right'`
| N ### SwipeCell Events 名称 | 参数 | 描述 -- | -- | -- change | `(value: string)` | 菜单展开或者收回后将菜单的状态传递给父组件,值为数组时表示分别控制左右滑动的展开和收起状态。 -click | `(context: SwipeActionClickContext)` | 操作项点击时触发(插槽写法组件不触发,业务侧自定义内容和事件)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
`interface SwipeActionClickContext { action: SwipeActionItem; source: 'left' | 'right' }`
+click | `(action: SwipeActionItem, source: SwipeSource)` | 操作项点击时触发(插槽写法组件不触发,业务侧自定义内容和事件)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
`type SwipeSource = 'left' \| 'right'`
+ +### SwipeCellInstanceFunctions 组件实例方法 + +名称 | 参数 | 返回值 | 描述 +-- | -- | -- | -- +showSure | `(sure: string | TNode, onClick?: SwipeActionItem['onClick'])` | `void` | 显示二次确认内容的函数。
【关于参数】`sure` 表示二次确认的具体内容,同content,TS 类型:`string | TNode`;如果设置了 `onClick`,则点击二次确认内容时,会执行此onClick方法。
[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。
diff --git a/src/swipe-cell/swipe-cell.vue b/src/swipe-cell/swipe-cell.vue index 1d21a3800..e90e583bd 100644 --- a/src/swipe-cell/swipe-cell.vue +++ b/src/swipe-cell/swipe-cell.vue @@ -1,164 +1,328 @@