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

fix(dialog): fix cancelBtn and confirmBtn slot not work #1668

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion src/dialog/__test__/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,34 @@ describe('dialog', () => {
expect(onClose).toHaveBeenCalledWith({ e: expect.any(MouseEvent), trigger: 'overlay' });
});
});

describe('slots', () => {
it(':confirmBtn', async () => {
const visible = true;
const confirmBtn = 'confirm';
const wrapper = mount(Dialog, {
props: {
visible,
},
slots: {
confirmBtn: `<button class="slot-confirm-btn">${confirmBtn}</button>`,
},
});
expect(wrapper.find('.slot-confirm-btn').text()).toBe(confirmBtn);
});
it(':cancelBtn', async () => {
const visible = true;
const cancelBtn = 'cancel';
const wrapper = mount(Dialog, {
props: {
visible,
},
slots: {
cancelBtn: `<button class="slot-cancel-btn">${cancelBtn}</button>`,
},
});
expect(wrapper.find('.slot-cancel-btn').text()).toBe(cancelBtn);
});
});
describe('event', () => {
it(':cancel && confirm && close', async () => {
const visible = true;
Expand Down
16 changes: 7 additions & 9 deletions src/dialog/dialog.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
name | type | default | description | required
-- | -- | -- | -- | --
actions | Array / Slot / Function | - | Typescript:`Array<ButtonProps>`,[Button API Documents](./button?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts) | N
buttonLayout | String | horizontal | optionshorizontal/vertical | N
buttonLayout | String | horizontal | options: horizontal/vertical | N
cancelBtn | String / Object / Slot / Function | - | Typescript:`string \| ButtonProps \| TNode \| null`,[Button API Documents](./button?tab=api)。[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/dialog/type.ts) | N
closeOnOverlayClick | Boolean | undefined | \- | N
closeBtn | Boolean | false | \- | N
closeOnOverlayClick | Boolean | false | \- | N
confirmBtn | String / Object / Slot / Function | - | Typescript:`string \| ButtonProps \| TNode \| null`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
content | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
destroyOnClose | Boolean | false | \- | N
overlayProps | Object | {} | \- | N
overlayProps | Object | {} | Typescript:`OverlayProps`,[Overlay API Documents](./overlay?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts) | N
preventScrollThrough | Boolean | true | \- | N
showOverlay | Boolean | true | \- | N
title | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
Expand All @@ -32,6 +33,7 @@ name | params | description
-- | -- | --
cancel | `(context: { e: MouseEvent })` | \-
close | `(context: DialogCloseContext)` | [see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts)。<br/>`type DialogEventSource = 'cancel' \| 'overlay'`<br/><br/>`interface DialogCloseContext { trigger: DialogEventSource; e: MouseEvent }`<br/>
closed | \- | \-
confirm | `(context: { e: MouseEvent })` | \-
overlay-click | `(context: { e: MouseEvent })` | \-

Expand Down Expand Up @@ -70,8 +72,6 @@ name | params | default | description
-- | -- | -- | --
options | \- | - | Typescript:`DialogOptions`

插件返回值:`DialogInstance`

### DialogPlugin.alert

同时也支持 `this.$dialog.alert`。
Expand All @@ -80,10 +80,8 @@ name | params | default | description
-- | -- | -- | --
options | Object | - | Typescript:`Omit<DialogOptions, 'cancelBtn'>`

插件返回值:`DialogInstance`


### CSS Variables

The component provides the following CSS variables, which can be used to customize styles.
Name | Default Value | Description
-- | -- | --
Expand All @@ -97,4 +95,4 @@ Name | Default Value | Description
--td-dialog-title-color | @font-gray-1 | -
--td-dialog-title-font-size | 18px | -
--td-dialog-title-line-height | 26px | -
--td-dialog-width | 311px | -
--td-dialog-width | 311px | -
26 changes: 12 additions & 14 deletions src/dialog/dialog.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
:: BASE_DOC ::

## API

### Dialog Props

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
actions | Array / Slot / Function | - | 操作栏。TS 类型:`Array<ButtonProps>`,[Button API Documents](./button?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts) | N
buttonLayout | String | horizontal | 多按钮排列方式。可选项:horizontal/vertical | N
cancelBtn | String / Object / Slot / Function | - | 取消按钮,可自定义。值为 null 则不显示取消按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性。使用 TNode 自定义按钮时,需自行控制取消事件。TS 类型:`string \| ButtonProps \| TNode \| null`,[Button API Documents](./button?tab=api)。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts) | N
closeBtn | Boolean | false | 多按钮排列方式。可选项:true/false | N
closeOnOverlayClick | Boolean | undefined | 点击蒙层时是否触发关闭事件 | N
closeOnOverlayClick | Boolean | false | 点击蒙层时是否触发关闭事件 | N
confirmBtn | String / Object / Slot / Function | - | 确认按钮。值为 null 则不显示确认按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性。使用 TNode 自定义按钮时,需自行控制确认事件。TS 类型:`string \| ButtonProps \| TNode \| null`。[通用类型定义](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
destroyOnClose | Boolean | false | 是否在关闭弹框的时候销毁子元素 | N
overlayProps | Object | {} | 透传至 Overlay 组件 | N
overlayProps | Object | {} | 透传至 Overlay 组件。TS 类型:`OverlayProps`,[Overlay API Documents](./overlay?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts) | N
preventScrollThrough | Boolean | true | 防止滚动穿透 | N
showOverlay | Boolean | true | 是否显示遮罩层 | N
title | String / Slot / Function | - | 标题。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
Expand All @@ -22,7 +23,7 @@ width | String / Number | - | 对话框宽度,示例:320, '500px', '80%' | N
zIndex | Number | - | 对话框层级,Web 侧样式默认为 2500,移动端和小程序样式默认为 1500 | N
onCancel | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>如果“取消”按钮存在,则点击“取消”按钮时触发,同时触发关闭事件 | N
onClose | Function | | TS 类型:`(context: DialogCloseContext) => void`<br/>关闭事件,点击 取消按钮 或 点击蒙层 时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts)。<br/>`type DialogEventSource = 'cancel' \| 'overlay'`<br/><br/>`interface DialogCloseContext { trigger: DialogEventSource; e: MouseEvent }`<br/> | N
onClosed | Function | | TS 类型:`() => void`<br/>组件关闭且动画结束后执行。 | N
onClosed | Function | | TS 类型:`() => void`<br/>对话框消失动画效果结束后触发 | N
onConfirm | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>如果“确认”按钮存在,则点击“确认”按钮时触发 | N
onOverlayClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>如果蒙层存在,点击蒙层时触发 | N

Expand All @@ -32,12 +33,13 @@ onOverlayClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void
-- | -- | --
cancel | `(context: { e: MouseEvent })` | 如果“取消”按钮存在,则点击“取消”按钮时触发,同时触发关闭事件
close | `(context: DialogCloseContext)` | 关闭事件,点击 取消按钮 或 点击蒙层 时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/dialog/type.ts)。<br/>`type DialogEventSource = 'cancel' \| 'overlay'`<br/><br/>`interface DialogCloseContext { trigger: DialogEventSource; e: MouseEvent }`<br/>
closed | \- | 对话框消失动画效果结束后触发
confirm | `(context: { e: MouseEvent })` | 如果“确认”按钮存在,则点击“确认”按钮时触发
overlay-click | `(context: { e: MouseEvent })` | 如果蒙层存在,点击蒙层时触发

### DialogOptions

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
className | String | - | 弹框类名,示例:'t-class-dialog-first t-class-dialog-second' | N
style | String / Object | - | 弹框 style 属性,输入 [CSSStyleDeclaration.cssText](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/cssText)。TS 类型:`string \| Styles`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
Expand All @@ -56,7 +58,7 @@ update | `(props: DialogOptions)` | \- | 必需。更新弹框内容

同时也支持 `this.$dialog`。

参数名称 | 参数类型 | 参数默认值 | 参数说明
参数名称 | 参数类型 | 参数默认值 | 参数描述
-- | -- | -- | --
options | \- | - | TS 类型:`DialogOptions`

Expand All @@ -66,24 +68,20 @@ options | \- | - | TS 类型:`DialogOptions`

同时也支持 `this.$dialog.confirm`。

参数名称 | 参数类型 | 参数默认值 | 参数说明
参数名称 | 参数类型 | 参数默认值 | 参数描述
-- | -- | -- | --
options | \- | - | TS 类型:`DialogOptions`

插件返回值:`DialogInstance`

### DialogPlugin.alert

同时也支持 `this.$dialog.alert`。

参数名称 | 参数类型 | 参数默认值 | 参数说明
参数名称 | 参数类型 | 参数默认值 | 参数描述
-- | -- | -- | --
options | Object | - | TS 类型:`Omit<DialogOptions, 'cancelBtn'>`

插件返回值:`DialogInstance`


### CSS Variables

组件提供了下列 CSS 变量,可用于自定义样式。
名称 | 默认值 | 描述
-- | -- | --
Expand All @@ -97,4 +95,4 @@ options | Object | - | TS 类型:`Omit<DialogOptions, 'cancelBtn'>`
--td-dialog-title-color | @font-gray-1 | -
--td-dialog-title-font-size | 18px | -
--td-dialog-title-line-height | 26px | -
--td-dialog-width | 311px | -
--td-dialog-width | 311px | -
58 changes: 38 additions & 20 deletions src/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ import { CloseIcon } from 'tdesign-icons-vue-next';
import { computed, defineComponent } from 'vue';
import get from 'lodash/get';
import isString from 'lodash/isString';
import isObject from 'lodash/isObject';

import TButton, { ButtonProps } from '../button';
import TPopup from '../popup';
import config from '../config';
import props from './props';
import { useTNodeJSX, useContent } from '../hooks/tnode';
import { usePrefixClass } from '../hooks/useClass';
import { TdDialogProps } from './type';

const { prefix } = config;

export default defineComponent({
name: `${prefix}-dialog`,
components: { TPopup, TButton, CloseIcon },
props,
emits: ['update:visible', 'confirm', 'overlay-click', 'cancel', 'close', 'closed'],
setup(props, context) {
Expand Down Expand Up @@ -77,20 +78,31 @@ export default defineComponent({
context.emit('overlay-click', { e });
};

const calcBtn = (btn: any) => (isString(btn) ? { content: btn } : btn);
const confirmBtnProps = computed(() => ({
const calcBtn = (btn: TdDialogProps['cancelBtn'] | TdDialogProps['confirmBtn']) => {
if (isString(btn)) {
return { content: btn };
}

if (isObject(btn)) {
return btn;
}

return {};
};

const confirmBtnProps = computed<ButtonProps>(() => ({
theme: 'primary',
...calcBtn(props.confirmBtn),
}));

const cancelBtnProps = computed<ButtonProps>(() => ({
theme: isTextStyleBtn.value ? 'default' : 'light',
...calcBtn(props.cancelBtn),
}));

const actionsBtnProps = computed(() => props.actions?.map((item) => calcBtn(item)));

return () => {
const { visible, showOverlay, overlayProps, preventScrollThrough, destroyOnClose, zIndex, closeBtn, actions } =
props;
const renderTitleNode = () => {
const titleNode = renderTNodeJSX('title');
if (!titleNode) {
Expand All @@ -114,43 +126,49 @@ export default defineComponent({
const actionsNode = renderTNodeJSX('actions');
if (actionsNode && actionsBtnProps.value) {
return actionsBtnProps.value.map((item, index) => (
<t-button key={index} {...item} class={buttonClass.value} onClick={handleCancel} />
<TButton key={index} {...item} class={buttonClass.value} onClick={handleCancel} />
));
}
return null;
};
const renderCancelBtnNode = () => {
const cancelBtnNode = renderTNodeJSX('cancelBtn');
if (!actions && cancelBtnNode) {
return <t-button {...cancelBtnProps.value} class={buttonClass.value} onClick={handleCancel} />;
if (!props.actions && cancelBtnNode) {
if (context.slots.cancelBtn) {
return cancelBtnNode;
}
return <TButton {...cancelBtnProps.value} class={buttonClass.value} onClick={handleCancel} />;
}
return null;
};

const renderConfirmBntNode = () => {
const confirmBtnNode = renderTNodeJSX('confirmBtn');
if (!actions && confirmBtnNode) {
return <t-button {...confirmBtnProps.value} class={buttonClass.value} onClick={handleConfirm} />;
if (!props.actions && confirmBtnNode) {
if (context.slots.confirmBtn) {
return confirmBtnNode;
}
return <TButton {...confirmBtnProps.value} class={buttonClass.value} onClick={handleConfirm} />;
}
return null;
};
return (
<t-popup
visible={visible}
<TPopup
visible={props.visible}
placement="center"
show-overlay={showOverlay}
overlay-props={overlayProps}
prevent-scroll-through={preventScrollThrough}
destroy-on-close={destroyOnClose}
z-index={zIndex}
show-overlay={props.showOverlay}
overlay-props={props.overlayProps}
prevent-scroll-through={props.preventScrollThrough}
destroy-on-close={props.destroyOnClose}
z-index={props.zIndex}
onClose={handleOverlayClick}
onClosed={handleClosed}
>
<div class={`${dialogClass.value} ${context.attrs.class || ''}`} style={rootStyles.value}>
{renderTNodeJSX('top')}
{closeBtn && (
{props.closeBtn && (
<div class={`${dialogClass.value}__close-btn`}>
<close-icon onClick={handleClose} />
<CloseIcon onClick={handleClose} />
</div>
)}
<div class={`${dialogClass.value}__content`}>
Expand All @@ -164,7 +182,7 @@ export default defineComponent({
{renderConfirmBntNode()}
</div>
</div>
</t-popup>
</TPopup>
);
};
},
Expand Down
2 changes: 1 addition & 1 deletion src/dialog/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default {
onCancel: Function as PropType<TdDialogProps['onCancel']>,
/** 关闭事件,点击 取消按钮 或 点击蒙层 时触发 */
onClose: Function as PropType<TdDialogProps['onClose']>,
/** 组件关闭且动画结束后执行 */
/** 对话框消失动画效果结束后触发 */
onClosed: Function as PropType<TdDialogProps['onClosed']>,
/** 如果“确认”按钮存在,则点击“确认”按钮时触发 */
onConfirm: Function as PropType<TdDialogProps['onConfirm']>,
Expand Down
10 changes: 8 additions & 2 deletions src/dialog/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* */

import { ButtonProps } from '../button';
import { OverlayProps } from '../overlay';
import { TNode, Styles } from '../common';

export interface TdDialogProps {
Expand All @@ -21,6 +22,11 @@ export interface TdDialogProps {
* 取消按钮,可自定义。值为 null 则不显示取消按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性。使用 TNode 自定义按钮时,需自行控制取消事件
*/
cancelBtn?: string | ButtonProps | TNode | null;
/**
* 多按钮排列方式。可选项:true/false
* @default false
*/
closeBtn?: boolean;
/**
* 点击蒙层时是否触发关闭事件
*/
Expand All @@ -42,7 +48,7 @@ export interface TdDialogProps {
* 透传至 Overlay 组件
* @default {}
*/
overlayProps?: object;
overlayProps?: OverlayProps;
/**
* 防止滚动穿透
* @default true
Expand Down Expand Up @@ -78,7 +84,7 @@ export interface TdDialogProps {
*/
onClose?: (context: DialogCloseContext) => void;
/**
* 组件关闭且动画结束后执行
* 对话框消失动画效果结束后触发
*/
onClosed?: () => void;
/**
Expand Down
Loading