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 drawer scroll through #98

Merged
merged 4 commits into from
Dec 28, 2021
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
2 changes: 1 addition & 1 deletion examples/drawer/drawer.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
:: BASE_DOC ::

## API

### Drawer Props

名称 | 类型 | 默认值 | 说明 | 必传
Expand All @@ -19,6 +18,7 @@ footer | Boolean / Slot / Function | true | 底部操作栏,默认会有“确
header | String / Boolean / Slot / Function | undefined | 头部内容。值为 true 显示空白头部,值为 false 不显示头部,值类型为 string 则直接显示值,值类型为 TNode 表示自定义头部内容。TS 类型:`string | boolean | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
mode | String | overlay | 展开方式,有两种:直接展示在内容上方 和 推开内容区域。可选项:overlay/push | N
placement | String | right | 抽屉方向。可选项:left/right/top/bottom | N
preventScrollThrough | Boolean | true | 防止滚动穿透 | N
showInAttachedElement | Boolean | false | 仅在挂载元素中显示抽屉,默认在浏览器可视区域显示。父元素需要有定位属性,如:position: relative | N
showOverlay | Boolean | true | 是否显示遮罩层 | N
size | String | small | 尺寸,支持 'small', 'medium', 'large','35px', '30%', '3em' 等。纵向抽屉调整的是抽屉宽度,横向抽屉调整的是抽屉高度 | N
Expand Down
26 changes: 12 additions & 14 deletions src/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import mixins from '../utils/mixins';
import getConfigReceiverMixins, { DialogConfig } from '../config-provider/config-receiver';
import TransferDom from '../utils/transfer-dom';
import { emitEvent } from '../utils/event';
import { addClass, removeClass } from '../utils/dom';
import { ClassName, Styles } from '../common';

const name = `${prefix}-dialog`;
const lockClass = `${prefix}-dialog--lock`;

function getCSSValue(v: string | number) {
return isNaN(Number(v)) ? v : `${Number(v)}px`;
Expand Down Expand Up @@ -116,17 +118,17 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('d

watch: {
visible(value) {
const { scrollWidth } = this;
let bodyCssText = 'overflow: hidden;';
if (value) {
const { scrollWidth } = this;
if (scrollWidth > 0) {
bodyCssText += `position: relative;width: calc(100% - ${scrollWidth}px);`;
const bodyCssText = `position: relative;width: calc(100% - ${scrollWidth}px);`;
document.body.style.cssText = bodyCssText;
}
document.body.style.cssText = bodyCssText;
addClass(document.body, lockClass);
} else {
document.body.style.cssText = '';
removeClass(document.body, lockClass);
}
this.disPreventScrollThrough(value);
this.addKeyboardEvent(value);
},
},
Expand All @@ -135,7 +137,6 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('d
},

beforeDestroy() {
this.disPreventScrollThrough(false);
this.addKeyboardEvent(false);
},

Expand All @@ -151,12 +152,6 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('d
},

methods: {
disPreventScrollThrough(disabled: boolean) {
// 防止滚动穿透,modal形态才需要
if (this.preventScrollThrough && this.isModal) {
document.body.style.overflow = disabled ? 'hidden' : '';
}
},
addKeyboardEvent(status: boolean) {
if (status) {
document.addEventListener('keydown', this.keyboardEvent);
Expand Down Expand Up @@ -233,7 +228,7 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('d
getIcon() {
const icon = {
info: <TIconInfoCircleFilled class={`${prefix}-is-info`} />,
warning: <TIconErrorCircleFilled class={`${prefix}-is-warning`}/>,
warning: <TIconErrorCircleFilled class={`${prefix}-is-warning`} />,
danger: <TIconErrorCircleFilled class={`${prefix}-is-error`} />,
success: <TIconCheckCircleFilled class={`${prefix}-is-success`} />,
};
Expand Down Expand Up @@ -272,7 +267,10 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DialogConfig>('d
style={this.dialogStyle}
v-draggable={this.isModeless && this.draggable}
>
<div class={`${name}__header`}>{this.getIcon()}{renderTNodeJSX(this, 'header', defaultHeader)}</div>
<div class={`${name}__header`}>
{this.getIcon()}
{renderTNodeJSX(this, 'header', defaultHeader)}
</div>
<span class={`${name}__close`} onClick={this.closeBtnAcion}>
{renderTNodeJSX(this, 'closeBtn', defaultCloseBtn)}
</span>
Expand Down
54 changes: 31 additions & 23 deletions src/drawer/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import mixins from '../utils/mixins';
import getConfigReceiverMixins, { DrawerConfig } from '../config-provider/config-receiver';
import TransferDom from '../utils/transfer-dom';
import { emitEvent } from '../utils/event';
import { addClass, removeClass } from '../utils/dom';
import { ClassName, Styles } from '../common';
import ActionMixin from '../dialog/actions';

type FooterButtonType = 'confirm' | 'cancel';

const name = `${prefix}-drawer`;
const lockClass = `${prefix}-drawer--lock`;

export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('drawer')).extend({
name: 'TDrawer',
Expand Down Expand Up @@ -44,11 +46,13 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('d
},
sizeValue(): string {
const defaultSize = isNaN(Number(this.size)) ? this.size : `${this.size}px`;
return {
small: '300px',
medium: '500px',
large: '760px',
}[this.size] || defaultSize;
return (
{
small: '300px',
medium: '500px',
large: '760px',
}[this.size] || defaultSize
);
},
wrapperStyles(): Styles {
return {
Expand All @@ -62,7 +66,7 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('d
return [`${name}__content-wrapper`, `${name}__content-wrapper--${this.placement}`];
},
parentNode(): HTMLElement {
return this.$el && this.$el.parentNode as HTMLElement;
return this.$el && (this.$el.parentNode as HTMLElement);
},
modeAndPlacement(): string {
return [this.mode, this.placement].join();
Expand All @@ -82,6 +86,16 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('d
},
immediate: true,
},
visible: {
handler(value) {
if (value && !this.showInAttachedElement) {
this.preventScrollThrough && addClass(document.body, lockClass);
} else {
this.preventScrollThrough && removeClass(document.body, lockClass);
}
},
immediate: true,
},
},

updated() {
Expand All @@ -100,19 +114,18 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('d
onkeydown={this.onKeyDown}
v-transfer-dom={this.attach}
>
{this.showOverlay && <div class={`${name}__mask`} onClick={this.handleWrapperClick}/>}
{this.showOverlay && <div class={`${name}__mask`} onClick={this.handleWrapperClick} />}
<div class={this.wrapperClasses} style={this.wrapperStyles}>
{this.header !== false ? <div class={`${name}__header`}>{renderTNodeJSX(this, 'header')}</div> : null}
{this.closeBtn !== false
? (
<div class={`${name}__close-btn`} onClick={this.handleCloseBtnClick}>
{renderTNodeJSX(this, 'closeBtn', defaultCloseBtn)}
</div>)
: null}
{this.closeBtn !== false ? (
<div class={`${name}__close-btn`} onClick={this.handleCloseBtnClick}>
{renderTNodeJSX(this, 'closeBtn', defaultCloseBtn)}
</div>
) : null}
<div class={`${name}__body`}>{body}</div>
{this.footer !== false
? <div class={`${name}__footer`}>{renderTNodeJSX(this, 'footer', defaultFooter)}</div>
: null }
{this.footer !== false ? (
<div class={`${name}__footer`}>{renderTNodeJSX(this, 'footer', defaultFooter)}</div>
) : null}
</div>
</div>
);
Expand Down Expand Up @@ -148,13 +161,8 @@ export default mixins(ActionMixin, getConfigReceiverMixins<Vue, DrawerConfig>('d
const theme = isCancel ? 'default' : 'primary';
const isApiObject = typeof btnApi === 'object';
return (
<t-button
theme={theme}
onClick={clickAction}
props={isApiObject ? btnApi : {}}
class={`${name}-${btnType}`}
>
{ (btnApi && typeof btnApi === 'object') ? btnApi.content : btnApi }
<t-button theme={theme} onClick={clickAction} props={isApiObject ? btnApi : {}} class={`${name}-${btnType}`}>
{btnApi && typeof btnApi === 'object' ? btnApi.content : btnApi}
</t-button>
);
},
Expand Down
7 changes: 6 additions & 1 deletion src/drawer/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* updated at 2021-12-01 14:26:00
* updated at 2021-12-26 14:30:54
* */

import { TdDrawerProps } from './type';
Expand Down Expand Up @@ -75,6 +75,11 @@ export default {
return ['left', 'right', 'top', 'bottom'].includes(val);
},
},
/** 防止滚动穿透 */
preventScrollThrough: {
type: Boolean,
default: true,
},
/** 仅在挂载元素中显示抽屉,默认在浏览器可视区域显示。父元素需要有定位属性,如:position: relative */
showInAttachedElement: Boolean,
/** 是否显示遮罩层 */
Expand Down
14 changes: 11 additions & 3 deletions src/drawer/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* updated at 2021-12-01 14:26:00
* updated at 2021-12-26 14:30:54
* */

import { ButtonProps } from '../button';
Expand Down Expand Up @@ -70,6 +70,11 @@ export interface TdDrawerProps {
* @default right
*/
placement?: 'left' | 'right' | 'top' | 'bottom';
/**
* 防止滚动穿透
* @default true
*/
preventScrollThrough?: boolean;
/**
* 仅在挂载元素中显示抽屉,默认在浏览器可视区域显示。父元素需要有定位属性,如:position: relative
* @default false
Expand Down Expand Up @@ -128,10 +133,13 @@ export interface TdDrawerProps {
* 如果蒙层存在,点击蒙层时触发
*/
onOverlayClick?: (context: { e: MouseEvent }) => void;
};
}

export type FooterButton = string | ButtonProps | TNode;

export type DrawerEventSource = 'esc' | 'close-btn' | 'cancel' | 'overlay';

export interface DrawerCloseContext { trigger: DrawerEventSource; e: MouseEvent | KeyboardEvent };
export interface DrawerCloseContext {
trigger: DrawerEventSource;
e: MouseEvent | KeyboardEvent;
}
37 changes: 13 additions & 24 deletions src/loading/loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ClassName, Styles } from '../common';
const name = `${prefix}-loading`;
const centerClass = `${prefix}-loading--center`;
const fullscreenClass = `${prefix}-loading__fullscreen`;
const lockClass = `${prefix}-loading-lock`;
const lockClass = `${prefix}-loading--lock`;
const overlayClass = `${prefix}-loading__overlay`;
const relativeClass = `${prefix}-loading__parent`;
const fullClass = `${prefix}-loading--full`;
Expand Down Expand Up @@ -67,11 +67,7 @@ export default Vue.extend({
return Boolean(this.text || this.$scopedSlots.text);
},
baseClasses(): ClassName {
return [
centerClass,
SIZE_CLASSNAMES[this.size],
{ [inheritColorClass]: this.inheritColor },
];
return [centerClass, SIZE_CLASSNAMES[this.size], { [inheritColorClass]: this.inheritColor }];
},
hasContent(): boolean {
return Boolean(this.default || this.$scopedSlots.default || this.content || this.$scopedSlots.content);
Expand Down Expand Up @@ -128,13 +124,10 @@ export default Vue.extend({
if (this.fullscreen) {
if (!this.loading) return null;
return (
<div
class={this.fullScreenClasses}
style={this.styles}
v-transfer-dom={this.attach}
>
<div class={this.fullScreenClasses} style={this.styles} v-transfer-dom={this.attach}>
<div class={this.baseClasses}>
{indicator}{text}
{indicator}
{text}
</div>
</div>
);
Expand All @@ -146,11 +139,9 @@ export default Vue.extend({
<div class={relativeClass}>
{renderContent(this, 'default', 'content')}
{this.showWrapLoading && (
<div
class={this.withContentClasses}
style={this.styles}
>
{indicator}{text}
<div class={this.withContentClasses} style={this.styles}>
{indicator}
{text}
</div>
)}
</div>
Expand All @@ -160,20 +151,18 @@ export default Vue.extend({
// transfer parent node
if (this.attach) {
return (
<div
class={this.attachClasses}
style={this.styles}
v-transfer-dom={this.attach}
>
{indicator}{text}
<div class={this.attachClasses} style={this.styles} v-transfer-dom={this.attach}>
{indicator}
{text}
</div>
);
}

// Normal Loading without overlay or content
return (
<div class={this.normalClasses} style={this.styles}>
{indicator}{text}
{indicator}
{text}
</div>
);
},
Expand Down
2 changes: 1 addition & 1 deletion src/loading/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { prefix } from '../config';
import { getAttach, removeClass } from '../utils/dom';
import { TdLoadingProps, LoadingInstance, LoadingMethod } from './type';

const lockClass = `${prefix}-loading-lock`;
const lockClass = `${prefix}-loading--lock`;

let fullScreenLoadingInstance: LoadingInstance = null;

Expand Down