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

feat(attach): support global attach config #3437

Merged
merged 13 commits into from
Dec 30, 2024
9 changes: 9 additions & 0 deletions src/config-provider/config-provider.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ name | type | default | description | required
alert | Object | - | Alert global configs。Typescript:`AlertConfig` | N
anchor | Object | - | Anchor global configs。Typescript:`AnchorConfig` | N
animation | Object | - | Typescript:`Partial<Record<'include'\|'exclude', Array<AnimationType>>>` `type AnimationType = 'ripple' \| 'expand' \| 'fade'`。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/config-provider/type.ts) | N
attach | String / Object / Function | - | Typescript:`AttachNode \| { popup?: AttachNode; dialog?: AttachNode; drawer?: AttachNode; }`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
calendar | Object | - | Calendar global configs。Typescript:`CalendarConfig` | N
cascader | Object | - | Cascader global configs。Typescript:`CascaderConfig` | N
classPrefix | String | t | \- | N
Expand All @@ -70,6 +71,7 @@ datePicker | Object | - | DatePicker global configs。Typescript:`DatePickerCo
descriptions | Object | - | Descriptions global configs。Typescript:`DescriptionsConfig` | N
dialog | Object | - | Dialog global configs。Typescript:`DialogConfig` | N
drawer | Object | - | Drawer global configs。Typescript:`DrawerConfig` | N
empty | Object | - | Empty global configs。Typescript:`EmptyConfig` | N
form | Object | - | Form global configs。Typescript:`FormConfig` | N
guide | Object | - | Guide global configs。Typescript:`GuideConfig` | N
icon | Object | - | icon config。Typescript:`IconConfig` `type IconConfig = GlobalIconConfig` `import { GlobalIconConfig } from '@icon'`。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/config-provider/type.ts) | N
Expand Down Expand Up @@ -390,3 +392,10 @@ skipButtonProps | Object | - | skip button. `{ content: 'Skip', theme: 'default'
name | type | default | description | required
-- | -- | -- | -- | --
rateText | Array | - | Typescript:`string[]` | N

### EmptyConfig

name | type | default | description | required
-- | -- | -- | -- | --
image | Object | - | Typescript:`{ maintenance: TNode; success: TNode; fail: TNode; empty: TNode; networkError: TNode; }`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
titleText | Object | - | Typescript:`{ maintenance: string; success: string; fail: string; empty: string; networkError: string; }` | N
9 changes: 9 additions & 0 deletions src/config-provider/config-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Vue.use(TDesign);
alert | Object | - | 警告全局配置。TS 类型:`AlertConfig` | N
anchor | Object | - | 锚点全局配置。TS 类型:`AnchorConfig` | N
animation | Object | - | 动画效果控制,`ripple` 指波纹动画, `expand` 指展开动画,`fade` 指渐变动画。默认为 `{ include: ['ripple','expand','fade'], exclude: [] }`。TS 类型:`Partial<Record<'include'\|'exclude', Array<AnimationType>>>` `type AnimationType = 'ripple' \| 'expand' \| 'fade'`。[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/config-provider/type.ts) | N
attach | String / Object / Function | - | TS 类型:`AttachNode \| { popup?: AttachNode; dialog?: AttachNode; drawer?: AttachNode; }`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
calendar | Object | - | 日历组件全局配置。TS 类型:`CalendarConfig` | N
cascader | Object | - | 级联选择器全局配置。TS 类型:`CascaderConfig` | N
classPrefix | String | t | CSS 类名前缀 | N
Expand All @@ -71,6 +72,7 @@ datePicker | Object | - | 日期选择器全局配置。TS 类型:`DatePickerC
descriptions | Object | - | 描述全局配置。TS 类型:`DescriptionsConfig` | N
dialog | Object | - | 对话框全局配置。TS 类型:`DialogConfig` | N
drawer | Object | - | 抽屉全局配置。TS 类型:`DrawerConfig` | N
empty | Object | - | 空状态全局配置。TS 类型:`EmptyConfig` | N
form | Object | - | 表单组件全局配置。TS 类型:`FormConfig` | N
guide | Object | - | 引导全局配置。TS 类型:`GuideConfig` | N
icon | Object | - | 图标全局配置。TS 类型:`IconConfig` `type IconConfig = GlobalIconConfig` `import { GlobalIconConfig } from '@icon'`。[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/config-provider/type.ts) | N
Expand Down Expand Up @@ -391,3 +393,10 @@ skipButtonProps | Object | - | 跳过按钮,示例:`{ content: '跳过', the
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
rateText | Array | - | 评分描述,默认值:['极差', '失望', '一般', '满意', '惊喜']。TS 类型:`string[]` | N

### EmptyConfig

名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
image | Object | - | 空状态组件各类型的图片配置。TS 类型:`{ maintenance: TNode; success: TNode; fail: TNode; empty: TNode; networkError: TNode; }`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
titleText | Object | - | 空状态组件各类型的标题文本配置。TS 类型:`{ maintenance: string; success: string; fail: string; empty: string; networkError: string; }` | N
20 changes: 20 additions & 0 deletions src/config-provider/config-receiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { GlobalIconConfig } from 'tdesign-icons-vue';
import { defaultGlobalConfig } from './context';
import { GlobalConfigProvider, AnimationType } from './type';

import type { AttachNode } from '../common';

export type ValueOf<T> = T[keyof T];

export type ComponentConfigType = ValueOf<GlobalConfigProvider>;
Expand Down Expand Up @@ -202,3 +204,21 @@ export function getClassPrefixMixins(componentName: string) {
},
});
}

// 用于非 composition api 的组件使用来自 config provider注入的 attach 使用
export function getAttachConfigMixins(componentName: string) {
uyarn marked this conversation as resolved.
Show resolved Hide resolved
return (Vue as VueConstructor<ConfigComponent>).extend({
name: 'TAttachProvider',
inject: {
globalConfig: {
default: undefined,
},
},
methods: {
globalAttach(): AttachNode {
// @ts-ignore
return this.globalConfig?.attach?.[componentName] || this.globalConfig?.attach || 'body';
},
},
});
}
6 changes: 5 additions & 1 deletion src/config-provider/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ButtonProps } from '../button';
import { FormErrorMessage } from '../form';
import { MessageOptions } from '../message';
import { ImageProps } from '../image';
import { TNode, SizeEnum } from '../common';
import { TNode, SizeEnum, AttachNode } from '../common';

export interface GlobalConfigProvider {
/**
Expand All @@ -25,6 +25,10 @@ export interface GlobalConfigProvider {
* 动画效果控制,`ripple` 指波纹动画, `expand` 指展开动画,`fade` 指渐变动画。默认为 `{ include: ['ripple','expand','fade'], exclude: [] }`
*/
animation?: Partial<Record<'include' | 'exclude', Array<AnimationType>>>;
/**
* null
*/
attach?: AttachNode | { imageViewer?: AttachNode; popup?: AttachNode; dialog?: AttachNode; drawer?: AttachNode };
/**
* 日历组件全局配置
*/
Expand Down
20 changes: 16 additions & 4 deletions src/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ import { DialogCloseContext, TdDialogProps } from './type';
import props from './props';
import { renderTNodeJSX, renderContent } from '../utils/render-tnode';
import mixins from '../utils/mixins';
import getConfigReceiverMixins, { DialogConfig, getGlobalIconMixins } from '../config-provider/config-receiver';
import getConfigReceiverMixins, {
DialogConfig,
getGlobalIconMixins,
getAttachConfigMixins,
} from '../config-provider/config-receiver';
import TransferDom from '../utils/transfer-dom';
import { emitEvent } from '../utils/event';
import { ClassName, Styles } from '../common';
import { AttachNode, ClassName, Styles } from '../common';
import { updateElement } from '../hooks/useDestroyOnClose';
import stack from './stack';
import { getScrollbarWidth } from '../_common/js/utils/getScrollbarWidth';
Expand All @@ -43,7 +47,12 @@ if (typeof window !== 'undefined' && window.document && window.document.document

let key = 1;

export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('dialog'), getGlobalIconMixins()).extend({
export default mixins(
ActionMixin,
getConfigReceiverMixins<Vue, DialogConfig>('dialog'),
getGlobalIconMixins(),
getAttachConfigMixins('dialog'),
).extend({
name: 'TDialog',

components: {
Expand Down Expand Up @@ -144,6 +153,9 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('d
computedDialogStyle(): Styles {
return !this.isFullScreen ? { width: getCSSValue(this.width), ...this.dialogStyle } : { ...this.dialogStyle }; // width全屏模式不生效;
},
computeAttach(): AttachNode {
return this.attach || this.globalAttach();
},
},

watch: {
Expand Down Expand Up @@ -518,7 +530,7 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('d
onBeforeLeave={this.beforeLeave}
onAfterLeave={this.afterLeave}
>
<div v-show={this.visible} class={this.ctxClass} style={ctxStyle} v-transfer-dom={this.attach}>
<div v-show={this.visible} class={this.ctxClass} style={ctxStyle} v-transfer-dom={this.computeAttach}>
{view}
</div>
</transition>
Expand Down
20 changes: 16 additions & 4 deletions src/drawer/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@ import props from './props';
import { FooterButton, DrawerCloseContext, TdDrawerProps } from './type';
import { renderTNodeJSX, renderContent } from '../utils/render-tnode';
import mixins from '../utils/mixins';
import getConfigReceiverMixins, { DrawerConfig, getGlobalIconMixins } from '../config-provider/config-receiver';
import getConfigReceiverMixins, {
DrawerConfig,
getGlobalIconMixins,
getAttachConfigMixins,
} from '../config-provider/config-receiver';
import TransferDom from '../utils/transfer-dom';
import { emitEvent } from '../utils/event';
import { ClassName, Styles } from '../common';
import { AttachNode, ClassName, Styles } from '../common';
import ActionMixin from '../dialog/actions';
import { getScrollbarWidth } from '../_common/js/utils/getScrollbarWidth';

type FooterButtonType = 'confirm' | 'cancel';

let key = 1;

export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('drawer'), getGlobalIconMixins()).extend({
export default mixins(
ActionMixin,
getConfigReceiverMixins<Vue, DrawerConfig>('drawer'),
getGlobalIconMixins(),
getAttachConfigMixins('drawer'),
).extend({
name: 'TDrawer',

components: {
Expand Down Expand Up @@ -110,6 +119,9 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('d
cursor: this.isHorizontal ? 'col-resize' : 'row-resize',
};
},
computeAttach(): AttachNode {
return this.attach || this.globalAttach();
},
},

watch: {
Expand Down Expand Up @@ -180,7 +192,7 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('d
class={this.drawerClasses}
style={{ zIndex: this.zIndex }}
onkeydown={this.onKeyDown}
v-transfer-dom={this.attach}
v-transfer-dom={this.computeAttach}
ref="drawerContainer"
tabindex={0}
v-show={this.visible}
Expand Down
5 changes: 3 additions & 2 deletions src/popup/popup.en-US.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
:: BASE_DOC ::

## API

### Popup Props

name | type | default | description | required
Expand All @@ -19,7 +20,7 @@ overlayStyle | Boolean / Object / Function | - | Typescript:`Styles \| ((trigg
placement | String | top | Typescript:`PopupPlacement` `type PopupPlacement = 'top'\|'left'\|'right'\|'bottom'\|'top-left'\|'top-right'\|'bottom-left'\|'bottom-right'\|'left-top'\|'left-bottom'\|'right-top'\|'right-bottom'`。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/popup/type.ts) | N
popperOptions | Object | - | popper initial options,details refer to https://popper.js.org/docs | N
showArrow | Boolean | false | \- | N
trigger | String | hover | optionshover/click/focus/mousedown/context-menu | N
trigger | String | hover | options: hover/click/focus/mousedown/context-menu | N
triggerElement | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
visible | Boolean | - | `v-model` is supported。Typescript:`boolean` | N
defaultVisible | Boolean | - | uncontrolled property。Typescript:`boolean` | N
Expand All @@ -44,4 +45,4 @@ name | params | default | description
-- | -- | -- | --
content | String / Slot / Function | - | required。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts)
popupProps | Object | - | \-
triggerElement | String | - | required
triggerElement | String | - | required
7 changes: 4 additions & 3 deletions src/popup/popup.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
{{ plugin }}

## API

### Popup Props

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
attach | String / Function | 'body' | 制定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body。TS 类型:`AttachNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
attach | String / Function | 'body' | 指定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body。TS 类型:`AttachNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
uyarn marked this conversation as resolved.
Show resolved Hide resolved
content | String / Slot / Function | - | 浮层里面的内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
default | String / Slot / Function | - | 触发元素,同 triggerElement。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
delay | Number / Array | - | 延时显示或隐藏浮层,[延迟显示的时间,延迟隐藏的时间],单位:毫秒。如果只有一个时间,则表示显示和隐藏的延迟时间相同。示例 `'300'` 或者 `[200, 200]`。默认为:[250, 150]。TS 类型:`number \| Array<number>` | N
Expand Down Expand Up @@ -54,4 +55,4 @@ visible-change | `(visible: boolean, context: PopupVisibleChangeContext)` | 当
-- | -- | -- | --
content | String / Slot / Function | - | 必需。气泡框的内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts)
popupProps | Object | - | 透传气泡框/浮层的属性
triggerElement | String | - | 必需。触发气泡框/浮层的元素,传入选择器即可
triggerElement | String | - | 必需。触发气泡框/浮层的元素,传入选择器即可
10 changes: 7 additions & 3 deletions src/popup/popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ import setStyle from '../_common/js/utils/set-style';
import props from './props';
import { PopupVisibleChangeContext, TdPopupProps } from './type';
import Container from './container';
import { getClassPrefixMixins } from '../config-provider/config-receiver';
import { getClassPrefixMixins, getAttachConfigMixins } from '../config-provider/config-receiver';
import mixins from '../utils/mixins';
import { emitEvent } from '../utils/event';
import {
getPopperPlacement, attachListeners, triggers, defaultVisibleDelay,
} from './utils';
import { AttachNode } from '../common';

const classPrefixMixins = getClassPrefixMixins('popup');

const injectionKey = '__T_POPUP';

export default mixins(classPrefixMixins).extend({
export default mixins(classPrefixMixins, getAttachConfigMixins('popup')).extend({
name: 'TPopup',

provide(this: any) {
Expand Down Expand Up @@ -89,6 +90,9 @@ export default mixins(classPrefixMixins).extend({
close: delay[1] ?? delay[0],
};
},
computeAttach(): AttachNode {
return this.attach || this.globalAttach();
},
},
watch: {
visible(visible) {
Expand Down Expand Up @@ -449,7 +453,7 @@ export default mixins(classPrefixMixins).extend({
}}
parent={this}
visible={visible}
attach={() => ({ attach: this.attach, current: this.$el })}
attach={() => ({ attach: this.computeAttach, current: this.$el })}
>
<transition
slot="content"
Expand Down
3 changes: 1 addition & 2 deletions src/popup/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import { TdPopupProps } from './type';
import { PropType } from 'vue';

export default {
/** 制定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body */
/** 指定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body */
attach: {
type: [String, Function] as PropType<TdPopupProps['attach']>,
default: 'body',
},
/** 浮层里面的内容 */
content: {
Expand Down
4 changes: 1 addition & 3 deletions src/popup/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@

import { TNode, ClassName, Styles, AttachNode } from '../common';

export type PopupMethod = (triggerElement: string, content: string | TNode, popupProps?: object) => void;

export interface TdPopupProps {
/**
* 制定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body
* 指定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body
* @default 'body'
*/
attach?: AttachNode;
Expand Down
Loading
Loading