Skip to content

Commit

Permalink
Merge pull request #98 from caoML/fix_scroll_through
Browse files Browse the repository at this point in the history
fix drawer scroll through
  • Loading branch information
chaishi committed Dec 28, 2021
2 parents 2709fbb + ff63c73 commit a0a62e4
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 68 deletions.
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

0 comments on commit a0a62e4

Please sign in to comment.