Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip]refactor(swipe-cell): sfc to tsx #1328

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
156 changes: 70 additions & 86 deletions src/swipe-cell/__test__/__snapshots__/demo.test.jsx.snap

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/swipe-cell/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import _SwipeCell from './swipe-cell.vue';
import _SwipeCell from './swipe-cell';
import { withInstall, WithInstallType } from '../shared';
import { TdSwipeCellProps } from './type';

Expand Down
10 changes: 5 additions & 5 deletions src/swipe-cell/swipe-cell.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ 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<SwipeActionItem>` | N
left | Array / Slot / Function | - | Typescript:`Array<SwipeActionItem> \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
opened | Boolean / Array | false | Typescript:`boolean \| Array<boolean>` | N
right | Array / Slot / Function | - | Typescript:`Array<SwipeActionItem>` `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
right | Array / Slot / Function | - | Typescript:`Array<SwipeActionItem> \| TNode ` `interface SwipeActionItem {text: string; className?: string; style?: string; sure?: string \| TNode; onClick?: () => void; [key: string]: any }`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts)。[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`<br/> | N
onClick | Function | | Typescript:`(action: SwipeActionItem, source: SwipeSource) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。<br/>`type SwipeSource = 'left' \| 'right'`<br/> | N

Expand All @@ -22,8 +22,8 @@ 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)。<br/>`type SwipeSource = 'left' \| 'right'`<br/>

### SwipeCellInstanceFunctions
### SwipeCellInstanceFunctions 组件实例方法

名称 | 参数 | 返回值 | 描述
name | params | return | description
-- | -- | -- | --
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)。<br/>
showSure | `(sure: string \| TNode, onClick?: SwipeActionItem['onClick'])` | `void` | Typescript:`string \| TNode;如果设置了 `onClick`,则点击二次确认内容时,会执行此onClick方法。<br />[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。<br/>`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts)
9 changes: 5 additions & 4 deletions src/swipe-cell/swipe-cell.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
:: BASE_DOC ::

## API

### SwipeCell Props

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
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
left | Array / Slot / Function | - | 左侧滑动操作项。所有行为同 `right`。TS 类型:`Array<SwipeActionItem>` | N
left | Array / Slot / Function | - | 左侧滑动操作项。所有行为同 `right`。TS 类型:`Array<SwipeActionItem> \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
opened | Boolean / Array | false | 操作项是否呈现为打开态,值为数组时表示分别控制左右滑动的展开和收起状态。TS 类型:`boolean \| Array<boolean>` | N
right | Array / Slot / Function | - | 右侧滑动操作项。有两种定义方式,一种是使用数组,二种是使用插槽。`right.text` 表示操作文本,`right.className` 表示操作项类名,`right.style` 表示操作项样式,`right.onClick` 表示点击操作项后执行的回调函数。示例:`[{ text: '删除', style: 'background-color: red', onClick: () => {} }]`。TS 类型:`Array<SwipeActionItem>` `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
right | Array / Slot / Function | - | 右侧滑动操作项。有两种定义方式,一种是使用数组,二种是使用插槽。`right.text` 表示操作文本,`right.className` 表示操作项类名,`right.style` 表示操作项样式,`right.onClick` 表示点击操作项后执行的回调函数。示例:`[{ text: '删除', style: 'background-color: red', onClick: () => {} }]`。TS 类型:`Array<SwipeActionItem> \| TNode ` `interface SwipeActionItem {text: string; className?: string; style?: string; sure?: string \| TNode; onClick?: () => void; [key: string]: any }`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts) | N
onChange | Function | | TS 类型:`(value: string) => void`<br/>菜单展开或者收回后将菜单的状态传递给父组件,值为数组时表示分别控制左右滑动的展开和收起状态。 | N
onClick | Function | | TS 类型:`(action: SwipeActionItem, source: SwipeSource) => void`<br/>操作项点击时触发(插槽写法组件不触发,业务侧自定义内容和事件)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。<br/>`type SwipeSource = 'left' \| 'right'`<br/> | N

Expand All @@ -25,4 +26,4 @@ click | `(action: SwipeActionItem, source: SwipeSource)` | 操作项点击时触

名称 | 参数 | 返回值 | 描述
-- | -- | -- | --
showSure | `(sure: string | TNode, onClick?: SwipeActionItem['onClick'])` | `void` | 显示二次确认内容的函数。<br/>【关于参数】`sure` 表示二次确认的具体内容,同contentTS 类型:`string | TNode`;如果设置了 `onClick`,则点击二次确认内容时,会执行此onClick方法。<br />[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。<br/>
showSure | `(sure: string \| TNode, onClick?: SwipeActionItem['onClick'])` | `void` | 显示二次确认内容的函数。<br/>【关于参数】`sure` 表示二次确认的具体内容,同contentTS 类型:`string \| TNode;如果设置了 `onClick`,则点击二次确认内容时,会执行此onClick方法。<br />[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/swipe-cell/type.ts)。<br/>`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts)
216 changes: 97 additions & 119 deletions src/swipe-cell/swipe-cell.vue → src/swipe-cell/swipe-cell.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,6 @@
<template>
<div ref="swipeCell" :class="classes" @click.capture="handleCellClick">
<div :style="wrapperStyle">
<div
ref="leftRef"
:class="classes + '__left'"
:style="{
width: initData.leftWidth ? `${initData.leftWidth}px` : 'auto',
}"
>
<t-node v-if="swipeLeftMenu" :content="swipeLeftMenu"></t-node>
<template v-else>
<template v-for="(btn, index) of left" :key="index">
<div
:class="[classes + '__content', btn.className || '']"
:style="btn.style || 'height: 100%;'"
@click="
handleClickBtn({
action: { ...btn },
source: 'left',
})
"
>
<t-node v-if="btn.icon" :class="classes + '__icon'" :content="btn.icon"></t-node>
<span v-if="btn.text" :class="classes + '__text'">
<t-node :content="btn.text"></t-node>
</span>
</div>
</template>
</template>
<div :style="sureLeftBgStyle"></div>
<div ref="sureLeftRef" :style="sureLeftStyle" @click="handleSureClick">
<t-node v-if="sureLeftContent" :content="sureLeftContent"></t-node>
</div>
</div>
<t-node v-if="swipeContent" :content="swipeContent"></t-node>
<div
ref="rightRef"
:class="classes + '__right'"
:style="{
width: initData.rightWidth ? `${initData.rightWidth}px` : 'auto',
}"
>
<t-node v-if="swipeRightMenu" :content="swipeRightMenu"></t-node>
<template v-else>
<template v-for="(btn, index) of right" :key="index">
<div
:class="[classes + '__content', btn.className || '']"
:style="btn.style || 'height: 100%;'"
@click="
handleClickBtn({
action: { ...btn },
source: 'right',
})
"
>
<t-node v-if="btn.icon" :class="classes + '__icon'" :content="btn.icon"></t-node>
<span v-if="btn.text" :class="classes + '__text'">
<t-node :content="btn.text"></t-node>
</span>
</div>
</template>
</template>
<div :style="sureRightBgStyle"></div>
<div ref="sureRightRef" :style="sureRightStyle" @click="handleSureClick">
<t-node v-if="sureRightContent" :content="sureRightContent"></t-node>
</div>
</div>
</div>
</div>
</template>

<script lang="ts">
import {
ref,
watch,
toRefs,
reactive,
computed,
onMounted,
Expand All @@ -90,9 +16,11 @@ import { useSwipe } from './useSwipe';
import props from './props';
import config from '../config';
import { SwipeActionItem } from './type';
import { renderContent, renderTNode, TNode, useClickAway } from '../shared';
import { useClickAway, useExpose } from '../shared';
import { preventDefault } from '../shared/dom';
import { useSureConfirm } from './useSureConfirm';
import { useContent, useTNodeJSX } from '../hooks/tnode';
import { usePrefixClass } from '../hooks/useClass';

const { prefix } = config;
const name = `${prefix}-swipe-cell`;
Expand All @@ -109,23 +37,19 @@ export interface SwipeInitData {

export default defineComponent({
name,
components: { TNode },
props,
emits: ['click', 'change'],
setup(props, context) {
const renderTNodeJSX = useTNodeJSX();
const renderTNodeContent = useContent();
const swipeCellClass = usePrefixClass('swipe-cell');

const internalInstance = getCurrentInstance();
const swipeContent = computed(() => renderContent(internalInstance, 'default', 'content'));
const swipeLeftMenu = computed(() =>
isFunction(props.left) || internalInstance?.slots.left ? renderTNode(internalInstance, 'left') : false,
);
const swipeRightMenu = computed(() =>
isFunction(props.right) || internalInstance?.slots.right ? renderTNode(internalInstance, 'right') : false,
);
const wrapperRef = ref<HTMLElement>();

const leftRef = ref<HTMLElement>();
const rightRef = ref<HTMLElement>();
const swipeCell = ref<HTMLElement>();
const wrapperStyle = computed(() => {
const swipeCellRef = ref<HTMLElement>();
const swipeCellStyle = computed(() => {
const transform = `translate3d(${initData.pos}px, 0, 0)`;
let transition = 'margin-left .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
transition += ',margin-right .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
Expand Down Expand Up @@ -175,7 +99,7 @@ export default defineComponent({
};
// 首次touchmove的方向,用于分开左右和上下滑动,左右滑动时禁止上下滑动,上下滑动时禁止左右滑动
let swipeDir: -1 | 0 | 1 = 0;
const { lengthX, lengthY, stop } = useSwipe(swipeCell, {
const { lengthX, lengthY, stop } = useSwipe(swipeCellRef, {
threshold: 0,
onSwipeStart: (e: TouchEvent) => {
if (props.disabled) {
Expand Down Expand Up @@ -284,7 +208,7 @@ export default defineComponent({
const updateLeftMenuPosStyle = (value?: number) => {
if (!leftRef.value) return;
const pos = value || initData.pos;
const children: string | any[] | HTMLCollection = leftRef.value.children || [];
const { children } = leftRef.value;
const wArr: number[] = [];
for (let i = 0, len = children.length - 2; i < len; ++i) {
const el = children[i] as HTMLElement;
Expand All @@ -301,7 +225,7 @@ export default defineComponent({
};
const stopClickAway = ref(
useClickAway(
swipeCell,
swipeCellRef,
() => {
close();
},
Expand Down Expand Up @@ -384,13 +308,13 @@ export default defineComponent({
if (autoBack) {
close();
}
if (action.onClick) {
if (action?.onClick) {
action.onClick();
return;
}
props.onClick?.({ action, source });
};
if (action.sure) {
if (action?.sure) {
showSure(action.sure, clickFn);
return;
}
Expand All @@ -401,39 +325,93 @@ export default defineComponent({
if (initData.moved) {
preventDefault(e, true);
}
e.stopPropagation();
};

context.expose({
showSure,
});
return {
...toRefs(props),
swipeContent,
swipeLeftMenu,
swipeRightMenu,
initData,
classes,
wrapperRef,
wrapperStyle,
swipeCell,
leftRef,
rightRef,
handleClickBtn,
end,
handleCellClick,
showSureRight,
showSureLeft,
sureLeftBgStyle,
sureRightBgStyle,
sureRightStyle,
sureLeftStyle,
sureRightRef,
sureLeftRef,
sureRightContent,
sureLeftContent,
showSure,
handleSureClick,
showSureRight: showSureRight.value,
swipeCell: swipeCellRef,
});

return () => {
const TNodeContent = renderTNodeContent('default', 'content');
const readerLeft = () => {
if (Array.isArray(props.left)) {
return props.left.map((btn) => {
const btnClass = [`${swipeCellClass.value}__content`, btn.className || ''];
const style = btn.style || 'height: 100%';
const { icon: btnIcon } = btn;
const { text: btnText } = btn;
return (
<div
class={btnClass}
style={style}
onClick={(e: MouseEvent) => handleClickBtn({ action: btn, source: 'left' })}
>
{btnIcon ? <btnIcon class={`${swipeCellClass.value}__icon`} /> : null}
{btnText ? <span class={`${swipeCellClass.value}__text`}>{btnText}</span> : null}
</div>
);
});
}
return renderTNodeJSX('left');
};
const readerRight = () => {
if (Array.isArray(props.right)) {
return props.right.map((btn) => {
const btnClass = [`${swipeCellClass.value}__content`, btn.className || ''];
const style = btn.style || 'height: 100%';
const { icon: btnIcon } = btn;
const { text: btnText } = btn;
return (
<div
class={btnClass}
style={style}
onClick={(e: MouseEvent) => handleClickBtn({ action: btn, source: 'right' })}
>
{btnIcon && <btnIcon class={`${swipeCellClass.value}__icon`}></btnIcon>}
{btnText && <span class={`${swipeCellClass.value}__text`}>{btnText}</span>}
</div>
);
});
}
return renderTNodeJSX('right');
};
return (
<div ref={swipeCellRef} class={swipeCellClass.value} onClick={handleCellClick}>
<div style={swipeCellStyle.value}>
<div
ref={leftRef}
class={`${swipeCellClass.value}__left`}
style={{
width: initData?.leftWidth ? `${initData.leftWidth}px` : 'auto',
}}
>
{readerLeft()}
<div style={sureLeftBgStyle.value}></div>
<div ref={sureLeftRef} style={sureLeftStyle.value} onClick={(e: MouseEvent) => handleSureClick}>
{sureLeftContent.value}
</div>
</div>
{TNodeContent}
<div
ref={rightRef}
class={`${swipeCellClass.value}__right`}
style={{
width: initData.rightWidth ? `${initData.rightWidth}px` : 'auto',
}}
>
{readerRight()}
<div style={sureRightBgStyle.value}></div>
<div ref={sureRightRef} style={sureRightStyle.value} onClick={(e: MouseEvent) => handleSureClick}>
{sureRightContent.value}
</div>
</div>
</div>
</div>
);
};
},
});
</script>
22 changes: 11 additions & 11 deletions src/swipe-cell/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface TdSwipeCellProps {
/**
* 左侧滑动操作项。所有行为同 `right`
*/
left?: Array<SwipeActionItem>;
left?: Array<SwipeActionItem> | TNode;
/**
* 操作项是否呈现为打开态,值为数组时表示分别控制左右滑动的展开和收起状态
* @default false
Expand All @@ -31,7 +31,7 @@ export interface TdSwipeCellProps {
/**
* 右侧滑动操作项。有两种定义方式,一种是使用数组,二种是使用插槽。`right.text` 表示操作文本,`right.className` 表示操作项类名,`right.style` 表示操作项样式,`right.onClick` 表示点击操作项后执行的回调函数。示例:`[{ text: '删除', style: 'background-color: red', onClick: () => {} }]`
*/
right?: Array<SwipeActionItem>;
right?: Array<SwipeActionItem> | TNode;
/**
* 菜单展开或者收回后将菜单的状态传递给父组件,值为数组时表示分别控制左右滑动的展开和收起状态。
*/
Expand All @@ -42,21 +42,21 @@ export interface TdSwipeCellProps {
onClick?: (action: SwipeActionItem, source: SwipeSource) => void;
}

/** 组件实例方法 */
export interface SwipeCellInstanceFunctions {
/**
* 显示二次确认内容的函数。<br/>【关于参数】`sure` 表示二次确认的具体内容,同content
*/
showSure?: (sure: string | TNode, onClick?: SwipeActionItem['onClick']) => void;
}

export interface SwipeActionItem {
text: string;
className?: string;
style?: string;
onClick?: () => void;
sure?: string | TNode;
onClick?: () => void;
[key: string]: any;
}

export type SwipeSource = 'left' | 'right';

/** 组件实例方法 */
export interface SwipeCellInstanceFunctions {
/**
* 显示二次确认内容
*/
showSure: (sure: string | TNode, onClick?: SwipeActionItem['onClick']) => void;
}