refactor: drawer #4708
parent
6596bd6255
commit
ba4adc27de
|
@ -1,38 +0,0 @@
|
||||||
import PropTypes from './vue-types';
|
|
||||||
import {
|
|
||||||
defineComponent,
|
|
||||||
nextTick,
|
|
||||||
onBeforeUnmount,
|
|
||||||
onMounted,
|
|
||||||
onUpdated,
|
|
||||||
ref,
|
|
||||||
Teleport,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'Portal',
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
getContainer: PropTypes.func.isRequired,
|
|
||||||
didUpdate: PropTypes.func,
|
|
||||||
},
|
|
||||||
setup(props, { slots }) {
|
|
||||||
const container = ref();
|
|
||||||
onMounted(() => {
|
|
||||||
container.value = props.getContainer();
|
|
||||||
});
|
|
||||||
onUpdated(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
props.nextTick?.(props);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
if (container.value && container.value.parentNode) {
|
|
||||||
container.value.parentNode.removeChild(container.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return () => {
|
|
||||||
return container.value ? <Teleport to={container.value}>{slots.default?.()}</Teleport> : null;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import PropTypes from './vue-types';
|
||||||
|
import { defineComponent, nextTick, onBeforeUnmount, onUpdated, Teleport } from 'vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Portal',
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: {
|
||||||
|
getContainer: PropTypes.func.isRequired,
|
||||||
|
didUpdate: PropTypes.func,
|
||||||
|
},
|
||||||
|
setup(props, { slots }) {
|
||||||
|
// getContainer 不会改变,不用响应式
|
||||||
|
const container = props.getContainer();
|
||||||
|
|
||||||
|
onUpdated(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
props.didUpdate?.(props);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (container && container.parentNode) {
|
||||||
|
container.parentNode.removeChild(container);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
return container ? <Teleport to={container} v-slots={slots}></Teleport> : null;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,150 +0,0 @@
|
||||||
import PropTypes from './vue-types';
|
|
||||||
import switchScrollingEffect from './switchScrollingEffect';
|
|
||||||
import setStyle from './setStyle';
|
|
||||||
import Portal from './Portal';
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
|
|
||||||
let openCount = 0;
|
|
||||||
const windowIsUndefined = !(
|
|
||||||
typeof window !== 'undefined' &&
|
|
||||||
window.document &&
|
|
||||||
window.document.createElement
|
|
||||||
);
|
|
||||||
// https://github.com/ant-design/ant-design/issues/19340
|
|
||||||
// https://github.com/ant-design/ant-design/issues/19332
|
|
||||||
let cacheOverflow = {};
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'PortalWrapper',
|
|
||||||
props: {
|
|
||||||
wrapperClassName: PropTypes.string,
|
|
||||||
forceRender: PropTypes.looseBool,
|
|
||||||
getContainer: PropTypes.any,
|
|
||||||
visible: PropTypes.looseBool,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
this._component = null;
|
|
||||||
const { visible } = this.$props;
|
|
||||||
openCount = visible ? openCount + 1 : openCount;
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(val) {
|
|
||||||
openCount = val ? openCount + 1 : openCount - 1;
|
|
||||||
},
|
|
||||||
getContainer(getContainer, prevGetContainer) {
|
|
||||||
const getContainerIsFunc =
|
|
||||||
typeof getContainer === 'function' && typeof prevGetContainer === 'function';
|
|
||||||
if (
|
|
||||||
getContainerIsFunc
|
|
||||||
? getContainer.toString() !== prevGetContainer.toString()
|
|
||||||
: getContainer !== prevGetContainer
|
|
||||||
) {
|
|
||||||
this.removeCurrentContainer(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
updated() {
|
|
||||||
this.setWrapperClassName();
|
|
||||||
},
|
|
||||||
beforeUnmount() {
|
|
||||||
const { visible } = this.$props;
|
|
||||||
// 离开时不会 render, 导到离开时数值不变,改用 func 。。
|
|
||||||
openCount = visible && openCount ? openCount - 1 : openCount;
|
|
||||||
this.removeCurrentContainer(visible);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getParent() {
|
|
||||||
const { getContainer } = this.$props;
|
|
||||||
if (getContainer) {
|
|
||||||
if (typeof getContainer === 'string') {
|
|
||||||
return document.querySelectorAll(getContainer)[0];
|
|
||||||
}
|
|
||||||
if (typeof getContainer === 'function') {
|
|
||||||
return getContainer();
|
|
||||||
}
|
|
||||||
if (typeof getContainer === 'object' && getContainer instanceof window.HTMLElement) {
|
|
||||||
return getContainer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return document.body;
|
|
||||||
},
|
|
||||||
|
|
||||||
getDomContainer() {
|
|
||||||
if (windowIsUndefined) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!this.container) {
|
|
||||||
this.container = document.createElement('div');
|
|
||||||
const parent = this.getParent();
|
|
||||||
if (parent) {
|
|
||||||
parent.appendChild(this.container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.setWrapperClassName();
|
|
||||||
return this.container;
|
|
||||||
},
|
|
||||||
|
|
||||||
setWrapperClassName() {
|
|
||||||
const { wrapperClassName } = this.$props;
|
|
||||||
if (this.container && wrapperClassName && wrapperClassName !== this.container.className) {
|
|
||||||
this.container.className = wrapperClassName;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
savePortal(c) {
|
|
||||||
// Warning: don't rename _component
|
|
||||||
// https://github.com/react-component/util/pull/65#discussion_r352407916
|
|
||||||
this._component = c;
|
|
||||||
},
|
|
||||||
|
|
||||||
removeCurrentContainer() {
|
|
||||||
this.container = null;
|
|
||||||
this._component = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enhance ./switchScrollingEffect
|
|
||||||
* 1. Simulate document body scroll bar with
|
|
||||||
* 2. Record body has overflow style and recover when all of PortalWrapper invisible
|
|
||||||
* 3. Disable body scroll when PortalWrapper has open
|
|
||||||
*
|
|
||||||
* @memberof PortalWrapper
|
|
||||||
*/
|
|
||||||
switchScrollingEffect() {
|
|
||||||
if (openCount === 1 && !Object.keys(cacheOverflow).length) {
|
|
||||||
switchScrollingEffect();
|
|
||||||
// Must be set after switchScrollingEffect
|
|
||||||
cacheOverflow = setStyle({
|
|
||||||
overflow: 'hidden',
|
|
||||||
overflowX: 'hidden',
|
|
||||||
overflowY: 'hidden',
|
|
||||||
});
|
|
||||||
} else if (!openCount) {
|
|
||||||
setStyle(cacheOverflow);
|
|
||||||
cacheOverflow = {};
|
|
||||||
switchScrollingEffect(true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { forceRender, visible } = this.$props;
|
|
||||||
let portal = null;
|
|
||||||
const childProps = {
|
|
||||||
getOpenCount: () => openCount,
|
|
||||||
getContainer: this.getDomContainer,
|
|
||||||
switchScrollingEffect: this.switchScrollingEffect,
|
|
||||||
};
|
|
||||||
if (forceRender || visible || this._component) {
|
|
||||||
portal = (
|
|
||||||
<Portal
|
|
||||||
getContainer={this.getDomContainer}
|
|
||||||
ref={this.savePortal}
|
|
||||||
v-slots={{ default: () => this.$slots.default?.(childProps) }}
|
|
||||||
></Portal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return portal;
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -0,0 +1,217 @@
|
||||||
|
import PropTypes from './vue-types';
|
||||||
|
import switchScrollingEffect from './switchScrollingEffect';
|
||||||
|
import setStyle from './setStyle';
|
||||||
|
import Portal from './Portal';
|
||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
onMounted,
|
||||||
|
onBeforeUnmount,
|
||||||
|
onUpdated,
|
||||||
|
getCurrentInstance,
|
||||||
|
} from 'vue';
|
||||||
|
import canUseDom from './canUseDom';
|
||||||
|
import ScrollLocker from '../vc-util/Dom/scrollLocker';
|
||||||
|
import wrapperRaf from './raf';
|
||||||
|
import { nextTick } from 'process';
|
||||||
|
|
||||||
|
let openCount = 0;
|
||||||
|
const supportDom = canUseDom();
|
||||||
|
|
||||||
|
/** @private Test usage only */
|
||||||
|
export function getOpenCount() {
|
||||||
|
return process.env.NODE_ENV === 'test' ? openCount : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/ant-design/ant-design/issues/19340
|
||||||
|
// https://github.com/ant-design/ant-design/issues/19332
|
||||||
|
let cacheOverflow = {};
|
||||||
|
|
||||||
|
const getParent = (getContainer: GetContainer) => {
|
||||||
|
if (!supportDom) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (getContainer) {
|
||||||
|
if (typeof getContainer === 'string') {
|
||||||
|
return document.querySelectorAll(getContainer)[0];
|
||||||
|
}
|
||||||
|
if (typeof getContainer === 'function') {
|
||||||
|
return getContainer();
|
||||||
|
}
|
||||||
|
if (typeof getContainer === 'object' && getContainer instanceof window.HTMLElement) {
|
||||||
|
return getContainer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return document.body;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetContainer = string | HTMLElement | (() => HTMLElement);
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'PortalWrapper',
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: {
|
||||||
|
wrapperClassName: PropTypes.string,
|
||||||
|
forceRender: PropTypes.looseBool,
|
||||||
|
getContainer: PropTypes.any,
|
||||||
|
visible: PropTypes.looseBool,
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const container = ref<HTMLElement>();
|
||||||
|
const componentRef = ref();
|
||||||
|
const rafId = ref<number>();
|
||||||
|
const scrollLocker = new ScrollLocker({
|
||||||
|
container: getParent(props.getContainer) as HTMLElement,
|
||||||
|
});
|
||||||
|
|
||||||
|
const removeCurrentContainer = () => {
|
||||||
|
// Portal will remove from `parentNode`.
|
||||||
|
// Let's handle this again to avoid refactor issue.
|
||||||
|
container.value?.parentNode?.removeChild(container.value);
|
||||||
|
};
|
||||||
|
const attachToParent = (force = false) => {
|
||||||
|
if (force || (container.value && !container.value.parentNode)) {
|
||||||
|
const parent = getParent(props.getContainer);
|
||||||
|
if (parent) {
|
||||||
|
parent.appendChild(container.value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// attachToParent();
|
||||||
|
|
||||||
|
const getContainer = () => {
|
||||||
|
if (!supportDom) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!container.value) {
|
||||||
|
container.value = document.createElement('div');
|
||||||
|
attachToParent(true);
|
||||||
|
}
|
||||||
|
setWrapperClassName();
|
||||||
|
return container.value;
|
||||||
|
};
|
||||||
|
const setWrapperClassName = () => {
|
||||||
|
const { wrapperClassName } = props;
|
||||||
|
if (container.value && wrapperClassName && wrapperClassName !== container.value.className) {
|
||||||
|
container.value.className = wrapperClassName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onUpdated(() => {
|
||||||
|
setWrapperClassName();
|
||||||
|
attachToParent();
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
* Enhance ./switchScrollingEffect
|
||||||
|
* 1. Simulate document body scroll bar with
|
||||||
|
* 2. Record body has overflow style and recover when all of PortalWrapper invisible
|
||||||
|
* 3. Disable body scroll when PortalWrapper has open
|
||||||
|
*
|
||||||
|
* @memberof PortalWrapper
|
||||||
|
*/
|
||||||
|
const switchScrolling = () => {
|
||||||
|
if (openCount === 1 && !Object.keys(cacheOverflow).length) {
|
||||||
|
switchScrollingEffect();
|
||||||
|
// Must be set after switchScrollingEffect
|
||||||
|
cacheOverflow = setStyle({
|
||||||
|
overflow: 'hidden',
|
||||||
|
overflowX: 'hidden',
|
||||||
|
overflowY: 'hidden',
|
||||||
|
});
|
||||||
|
} else if (!openCount) {
|
||||||
|
setStyle(cacheOverflow);
|
||||||
|
cacheOverflow = {};
|
||||||
|
switchScrollingEffect(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
onMounted(() => {
|
||||||
|
let init = false;
|
||||||
|
watch(
|
||||||
|
[() => props.visible, () => props.getContainer],
|
||||||
|
([visible, getContainer], [prevVisible, prevGetContainer]) => {
|
||||||
|
// Update count
|
||||||
|
if (supportDom && getParent(props.getContainer) === document.body) {
|
||||||
|
if (visible && !prevVisible) {
|
||||||
|
openCount += 1;
|
||||||
|
} else if (init) {
|
||||||
|
openCount -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init) {
|
||||||
|
// Clean up container if needed
|
||||||
|
const getContainerIsFunc =
|
||||||
|
typeof getContainer === 'function' && typeof prevGetContainer === 'function';
|
||||||
|
if (
|
||||||
|
getContainerIsFunc
|
||||||
|
? getContainer.toString() !== prevGetContainer.toString()
|
||||||
|
: getContainer !== prevGetContainer
|
||||||
|
) {
|
||||||
|
removeCurrentContainer();
|
||||||
|
}
|
||||||
|
// updateScrollLocker
|
||||||
|
if (
|
||||||
|
visible &&
|
||||||
|
visible !== prevVisible &&
|
||||||
|
supportDom &&
|
||||||
|
getParent(getContainer) !== scrollLocker.getContainer()
|
||||||
|
) {
|
||||||
|
scrollLocker.reLock({
|
||||||
|
container: getParent(getContainer) as HTMLElement,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
init = true;
|
||||||
|
},
|
||||||
|
{ immediate: true, flush: 'post' },
|
||||||
|
);
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
if (!attachToParent()) {
|
||||||
|
rafId.value = wrapperRaf(() => {
|
||||||
|
instance.update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
const { visible, getContainer } = props;
|
||||||
|
if (supportDom && getParent(getContainer) === document.body) {
|
||||||
|
// 离开时不会 render, 导到离开时数值不变,改用 func 。。
|
||||||
|
openCount = visible && openCount ? openCount - 1 : openCount;
|
||||||
|
}
|
||||||
|
removeCurrentContainer();
|
||||||
|
wrapperRaf.cancel(rafId.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
const { forceRender, visible } = props;
|
||||||
|
let portal = null;
|
||||||
|
const childProps = {
|
||||||
|
getOpenCount: () => openCount,
|
||||||
|
getContainer,
|
||||||
|
switchScrollingEffect: switchScrolling,
|
||||||
|
scrollLocker,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (forceRender || visible || componentRef.value) {
|
||||||
|
portal = (
|
||||||
|
<Portal
|
||||||
|
getContainer={getContainer}
|
||||||
|
ref={componentRef}
|
||||||
|
v-slots={{ default: () => slots.default?.(childProps) }}
|
||||||
|
></Portal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return portal;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Portal',
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: ['getContainer'],
|
||||||
|
setup(_props, { slots }) {
|
||||||
|
return () => {
|
||||||
|
return slots.default?.();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
|
@ -4,7 +4,7 @@ import dayjs from 'dayjs';
|
||||||
import DatePicker from '../';
|
import DatePicker from '../';
|
||||||
import { openPicker, selectCell, closePicker } from './utils';
|
import { openPicker, selectCell, closePicker } from './utils';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
|
jest.mock('../../_util/Portal');
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
describe('RangePicker', () => {
|
describe('RangePicker', () => {
|
||||||
|
|
|
@ -13,211 +13,207 @@ exports[`RangePicker customize separator 1`] = `
|
||||||
|
|
||||||
exports[`RangePicker show month panel according to value 1`] = `
|
exports[`RangePicker show month panel according to value 1`] = `
|
||||||
<div data-v-app="">
|
<div data-v-app="">
|
||||||
<!--teleport start-->
|
<div>
|
||||||
<!--teleport end-->
|
<!---->
|
||||||
|
<div class="ant-picker-dropdown ant-picker-dropdown-range" style="opacity: 0; pointer-events: none;">
|
||||||
|
<div class="ant-picker-range-wrapper ant-picker-date-range-wrapper" style="min-width: 0px;">
|
||||||
|
<div class="ant-picker-range-arrow" style="left: 0px;"></div>
|
||||||
|
<div class="ant-picker-panel-container" style="margin-left: 0px;">
|
||||||
|
<div class="ant-picker-panels">
|
||||||
|
<div tabindex="0" class="ant-picker-panel ant-picker-panel-has-range ant-picker-panel-focused">
|
||||||
|
<div class="ant-picker-datetime-panel">
|
||||||
|
<div class="ant-picker-date-panel">
|
||||||
|
<div class="ant-picker-header"><button type="button" tabindex="-1" class="ant-picker-header-super-prev-btn">«</button><button type="button" tabindex="-1" class="ant-picker-header-prev-btn">‹</button>
|
||||||
|
<div class="ant-picker-header-view"><button type="button" tabindex="-1" class="ant-picker-month-btn">Jan</button><button type="button" tabindex="-1" class="ant-picker-year-btn">2000</button></div><button type="button" tabindex="-1" class="ant-picker-header-next-btn">›</button><button type="button" tabindex="-1" class="ant-picker-header-super-next-btn">»</button>
|
||||||
|
</div>
|
||||||
|
<div class="ant-picker-body">
|
||||||
|
<table class="ant-picker-content">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Su</th>
|
||||||
|
<th>Mo</th>
|
||||||
|
<th>Tu</th>
|
||||||
|
<th>We</th>
|
||||||
|
<th>Th</th>
|
||||||
|
<th>Fr</th>
|
||||||
|
<th>Sa</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td title="1999-12-26" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">26</div>
|
||||||
|
</td>
|
||||||
|
<td title="1999-12-27" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">27</div>
|
||||||
|
</td>
|
||||||
|
<td title="1999-12-28" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">28</div>
|
||||||
|
</td>
|
||||||
|
<td title="1999-12-29" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">29</div>
|
||||||
|
</td>
|
||||||
|
<td title="1999-12-30" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">30</div>
|
||||||
|
</td>
|
||||||
|
<td title="1999-12-31" class="ant-picker-cell ant-picker-cell-end">
|
||||||
|
<div class="ant-picker-cell-inner">31</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-01" class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view ant-picker-cell-range-start ant-picker-cell-range-end ant-picker-cell-selected">
|
||||||
|
<div class="ant-picker-cell-inner">1</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td title="2000-01-02" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">2</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-03" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">3</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-04" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">4</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-05" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">5</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-06" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">6</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-07" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">7</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-08" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">8</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td title="2000-01-09" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">9</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-10" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">10</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-11" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">11</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-12" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">12</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-13" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">13</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-14" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">14</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-15" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">15</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td title="2000-01-16" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">16</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-17" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">17</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-18" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">18</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-19" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">19</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-20" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">20</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-21" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">21</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-22" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">22</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td title="2000-01-23" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">23</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-24" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">24</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-25" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">25</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-26" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">26</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-27" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">27</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-28" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">28</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-29" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">29</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td title="2000-01-30" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">30</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-01-31" class="ant-picker-cell ant-picker-cell-in-view">
|
||||||
|
<div class="ant-picker-cell-inner">31</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-02-01" class="ant-picker-cell ant-picker-cell-start">
|
||||||
|
<div class="ant-picker-cell-inner">1</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-02-02" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">2</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-02-03" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">3</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-02-04" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">4</div>
|
||||||
|
</td>
|
||||||
|
<td title="2000-02-05" class="ant-picker-cell">
|
||||||
|
<div class="ant-picker-cell-inner">5</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ant-picker-time-panel">
|
||||||
|
<div class="ant-picker-header">
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<div class="ant-picker-header-view">2000/01/01</div>
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div class="ant-picker-content"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ant-picker-footer">
|
||||||
|
<!---->
|
||||||
|
<ul class="ant-picker-ranges">
|
||||||
|
<!---->
|
||||||
|
<li class="ant-picker-ok"><button class="ant-btn ant-btn-primary ant-btn-sm" type="button">
|
||||||
|
<!----><span>Ok</span>
|
||||||
|
</button></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="ant-picker ant-picker-range">
|
<div class="ant-picker ant-picker-range">
|
||||||
<div class="ant-picker-input ant-picker-input-active"><input readonly="" placeholder="Start date" size="12" autocomplete="off"></div>
|
<div class="ant-picker-input ant-picker-input-active"><input readonly="" placeholder="Start date" size="12" autocomplete="off"></div>
|
||||||
<div class="ant-picker-range-separator"><span aria-label="to" class="ant-picker-separator"><span role="img" aria-label="swap-right" class="anticon anticon-swap-right"><svg focusable="false" class="" data-icon="swap-right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"></path></svg></span></span></div>
|
<div class="ant-picker-range-separator"><span aria-label="to" class="ant-picker-separator"><span role="img" aria-label="swap-right" class="anticon anticon-swap-right"><svg focusable="false" class="" data-icon="swap-right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"></path></svg></span></span></div>
|
||||||
<div class="ant-picker-input"><input readonly="" placeholder="End date" size="12" autocomplete="off"></div>
|
<div class="ant-picker-input"><input readonly="" placeholder="End date" size="12" autocomplete="off"></div>
|
||||||
<div class="ant-picker-active-bar" style="left: 0px; width: 0px; position: absolute;"></div><span class="ant-picker-suffix"><span role="img" aria-label="calendar" class="anticon anticon-calendar"><svg focusable="false" class="" data-icon="calendar" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"></path></svg></span></span>
|
<div class="ant-picker-active-bar" style="left: 0px; width: 0px; position: absolute;"></div><span class="ant-picker-suffix"><span role="img" aria-label="calendar" class="anticon anticon-calendar"><svg focusable="false" class="" data-icon="calendar" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"></path></svg></span></span><span class="ant-picker-clear"><span role="img" aria-label="close-circle" class="anticon anticon-close-circle"><svg focusable="false" class="" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></span></span>
|
||||||
<div style="position: absolute; top: 0px; left: 0px; width: 100%;">
|
|
||||||
<div>
|
|
||||||
<!---->
|
|
||||||
<div class="ant-picker-dropdown ant-picker-dropdown-range" style="opacity: 0; pointer-events: none;">
|
|
||||||
<div class="ant-picker-range-wrapper ant-picker-date-range-wrapper" style="min-width: 0px;">
|
|
||||||
<div class="ant-picker-range-arrow" style="left: 0px;"></div>
|
|
||||||
<div class="ant-picker-panel-container" style="margin-left: 0px;">
|
|
||||||
<div class="ant-picker-panels">
|
|
||||||
<div tabindex="0" class="ant-picker-panel ant-picker-panel-has-range ant-picker-panel-focused">
|
|
||||||
<div class="ant-picker-datetime-panel">
|
|
||||||
<div class="ant-picker-date-panel">
|
|
||||||
<div class="ant-picker-header"><button type="button" tabindex="-1" class="ant-picker-header-super-prev-btn">«</button><button type="button" tabindex="-1" class="ant-picker-header-prev-btn">‹</button>
|
|
||||||
<div class="ant-picker-header-view"><button type="button" tabindex="-1" class="ant-picker-month-btn">Jan</button><button type="button" tabindex="-1" class="ant-picker-year-btn">2000</button></div><button type="button" tabindex="-1" class="ant-picker-header-next-btn">›</button><button type="button" tabindex="-1" class="ant-picker-header-super-next-btn">»</button>
|
|
||||||
</div>
|
|
||||||
<div class="ant-picker-body">
|
|
||||||
<table class="ant-picker-content">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Su</th>
|
|
||||||
<th>Mo</th>
|
|
||||||
<th>Tu</th>
|
|
||||||
<th>We</th>
|
|
||||||
<th>Th</th>
|
|
||||||
<th>Fr</th>
|
|
||||||
<th>Sa</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td title="1999-12-26" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">26</div>
|
|
||||||
</td>
|
|
||||||
<td title="1999-12-27" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">27</div>
|
|
||||||
</td>
|
|
||||||
<td title="1999-12-28" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">28</div>
|
|
||||||
</td>
|
|
||||||
<td title="1999-12-29" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">29</div>
|
|
||||||
</td>
|
|
||||||
<td title="1999-12-30" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">30</div>
|
|
||||||
</td>
|
|
||||||
<td title="1999-12-31" class="ant-picker-cell ant-picker-cell-end">
|
|
||||||
<div class="ant-picker-cell-inner">31</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-01" class="ant-picker-cell ant-picker-cell-start ant-picker-cell-in-view ant-picker-cell-range-start ant-picker-cell-range-end ant-picker-cell-selected">
|
|
||||||
<div class="ant-picker-cell-inner">1</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td title="2000-01-02" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">2</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-03" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">3</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-04" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">4</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-05" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">5</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-06" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">6</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-07" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">7</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-08" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">8</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td title="2000-01-09" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">9</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-10" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">10</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-11" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">11</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-12" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">12</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-13" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">13</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-14" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">14</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-15" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">15</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td title="2000-01-16" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">16</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-17" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">17</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-18" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">18</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-19" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">19</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-20" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">20</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-21" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">21</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-22" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">22</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td title="2000-01-23" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">23</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-24" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">24</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-25" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">25</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-26" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">26</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-27" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">27</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-28" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">28</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-29" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">29</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td title="2000-01-30" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">30</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-01-31" class="ant-picker-cell ant-picker-cell-in-view">
|
|
||||||
<div class="ant-picker-cell-inner">31</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-02-01" class="ant-picker-cell ant-picker-cell-start">
|
|
||||||
<div class="ant-picker-cell-inner">1</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-02-02" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">2</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-02-03" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">3</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-02-04" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">4</div>
|
|
||||||
</td>
|
|
||||||
<td title="2000-02-05" class="ant-picker-cell">
|
|
||||||
<div class="ant-picker-cell-inner">5</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ant-picker-time-panel">
|
|
||||||
<div class="ant-picker-header">
|
|
||||||
<!---->
|
|
||||||
<!---->
|
|
||||||
<div class="ant-picker-header-view">2000/01/01</div>
|
|
||||||
<!---->
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
<div class="ant-picker-content"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ant-picker-footer">
|
|
||||||
<!---->
|
|
||||||
<ul class="ant-picker-ranges">
|
|
||||||
<!---->
|
|
||||||
<li class="ant-picker-ok"><button class="ant-btn ant-btn-primary ant-btn-sm" type="button">
|
|
||||||
<!----><span>Ok</span>
|
|
||||||
</button></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div><span class="ant-picker-clear"><span role="img" aria-label="close-circle" class="anticon anticon-close-circle"><svg focusable="false" class="" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></span></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -16,7 +16,7 @@ const DrawerCom = {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
wrapClassName: {
|
class: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
@ -106,6 +106,7 @@ describe('Drawer', () => {
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
closable: false,
|
closable: false,
|
||||||
getContainer: false,
|
getContainer: false,
|
||||||
|
visible: true,
|
||||||
},
|
},
|
||||||
slots: {
|
slots: {
|
||||||
default: () => 'Here is content of Drawer',
|
default: () => 'Here is content of Drawer',
|
||||||
|
@ -121,7 +122,8 @@ describe('Drawer', () => {
|
||||||
it('class is test_drawer', async () => {
|
it('class is test_drawer', async () => {
|
||||||
const props = {
|
const props = {
|
||||||
props: {
|
props: {
|
||||||
wrapClassName: 'test_drawer',
|
class: 'test_drawer',
|
||||||
|
visible: true,
|
||||||
},
|
},
|
||||||
sync: false,
|
sync: false,
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,14 +38,14 @@ const MultiDrawer = {
|
||||||
width: 520,
|
width: 520,
|
||||||
visible: this.visible,
|
visible: this.visible,
|
||||||
getContainer: false,
|
getContainer: false,
|
||||||
className: 'test_drawer',
|
class: 'test_drawer',
|
||||||
placement: this.placement,
|
placement: this.placement,
|
||||||
onClose: this.onClose,
|
onClose: this.onClose,
|
||||||
};
|
};
|
||||||
const childrenDrawerProps = {
|
const childrenDrawerProps = {
|
||||||
title: 'Two-level Drawer',
|
title: 'Two-level Drawer',
|
||||||
width: 320,
|
width: 320,
|
||||||
className: 'Two-level',
|
class: 'Two-level',
|
||||||
visible: this.childrenDrawer,
|
visible: this.childrenDrawer,
|
||||||
getContainer: false,
|
getContainer: false,
|
||||||
placement: this.placement,
|
placement: this.placement,
|
||||||
|
@ -112,7 +112,7 @@ describe('Drawer', () => {
|
||||||
wrapper.find('#open_two_drawer').trigger('click');
|
wrapper.find('#open_two_drawer').trigger('click');
|
||||||
}, 0);
|
}, 0);
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
const translateX = wrapper.find('.test_drawer').find('.ant-drawer').element.style.transform;
|
const translateX = wrapper.find('.test_drawer').element.style.transform;
|
||||||
expect(translateX).toEqual('translateX(-180px)');
|
expect(translateX).toEqual('translateX(-180px)');
|
||||||
expect(wrapper.find('#two_drawer_text').exists()).toBe(true);
|
expect(wrapper.find('#two_drawer_text').exists()).toBe(true);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
@ -133,7 +133,7 @@ describe('Drawer', () => {
|
||||||
wrapper.find('#open_two_drawer').trigger('click');
|
wrapper.find('#open_two_drawer').trigger('click');
|
||||||
}, 0);
|
}, 0);
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
const translateX = wrapper.find('.test_drawer').find('.ant-drawer').element.style.transform;
|
const translateX = wrapper.find('.test_drawer').element.style.transform;
|
||||||
expect(translateX).toEqual('translateX(180px)');
|
expect(translateX).toEqual('translateX(180px)');
|
||||||
expect(wrapper.find('#two_drawer_text').exists()).toBe(true);
|
expect(wrapper.find('#two_drawer_text').exists()).toBe(true);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
@ -153,7 +153,7 @@ describe('Drawer', () => {
|
||||||
wrapper.find('#open_two_drawer').trigger('click');
|
wrapper.find('#open_two_drawer').trigger('click');
|
||||||
}, 0);
|
}, 0);
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
const translateY = wrapper.find('.test_drawer').find('.ant-drawer').element.style.transform;
|
const translateY = wrapper.find('.test_drawer').element.style.transform;
|
||||||
expect(translateY).toEqual('translateY(180px)');
|
expect(translateY).toEqual('translateY(180px)');
|
||||||
expect(wrapper.find('#two_drawer_text').exists()).toBe(true);
|
expect(wrapper.find('#two_drawer_text').exists()).toBe(true);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`Drawer class is test_drawer 1`] = `
|
exports[`Drawer class is test_drawer 1`] = `
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-right" tabindex="-1">
|
<div tabindex="-1" class="ant-drawer ant-drawer-right test_drawer">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
|
@ -17,16 +17,17 @@ exports[`Drawer class is test_drawer 1`] = `
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Drawer closable is false 1`] = `
|
exports[`Drawer closable is false 1`] = `
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-right ant-drawer-open" tabindex="-1">
|
<div tabindex="-1" class="ant-drawer ant-drawer-right">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="width: 378px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
<div class="ant-drawer-wrapper-body">
|
<div class="ant-drawer-wrapper-body">
|
||||||
<!---->
|
<!---->
|
||||||
|
@ -34,33 +35,35 @@ exports[`Drawer closable is false 1`] = `
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Drawer destroyOnClose is true 1`] = `
|
exports[`Drawer destroyOnClose is true 1`] = `
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-right" tabindex="-1">
|
<div tabindex="-1" class="ant-drawer ant-drawer-right">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
<div class="ant-drawer-wrapper-body" style="opacity: 0; transition: opacity .3s;">
|
<div class="ant-drawer-wrapper-body">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="ant-drawer-body">Here is content of Drawer</div>
|
<div class="ant-drawer-body">Here is content of Drawer</div>
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Drawer have a title 1`] = `
|
exports[`Drawer have a title 1`] = `
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-right ant-drawer-open" tabindex="-1">
|
<div tabindex="-1" class="ant-drawer ant-drawer-right">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="width: 378px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
<div class="ant-drawer-wrapper-body">
|
<div class="ant-drawer-wrapper-body">
|
||||||
<div class="ant-drawer-header">
|
<div class="ant-drawer-header">
|
||||||
|
@ -73,16 +76,17 @@ exports[`Drawer have a title 1`] = `
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Drawer render correctly 1`] = `
|
exports[`Drawer render correctly 1`] = `
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-right ant-drawer-open" tabindex="-1">
|
<div tabindex="-1" class="ant-drawer ant-drawer-right">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="width: 400px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 400px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
<div class="ant-drawer-wrapper-body">
|
<div class="ant-drawer-wrapper-body">
|
||||||
<div class="ant-drawer-header ant-drawer-header-close-only">
|
<div class="ant-drawer-header ant-drawer-header-close-only">
|
||||||
|
@ -95,16 +99,17 @@ exports[`Drawer render correctly 1`] = `
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Drawer render top drawer 1`] = `
|
exports[`Drawer render top drawer 1`] = `
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-top ant-drawer-open" tabindex="-1">
|
<div tabindex="-1" class="ant-drawer ant-drawer-top">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="height: 400px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateY(-100%); height: 400px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
<div class="ant-drawer-wrapper-body">
|
<div class="ant-drawer-wrapper-body">
|
||||||
<div class="ant-drawer-header ant-drawer-header-close-only">
|
<div class="ant-drawer-header ant-drawer-header-close-only">
|
||||||
|
@ -117,6 +122,7 @@ exports[`Drawer render top drawer 1`] = `
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,8 +4,8 @@ exports[`Drawer render correctly 1`] = `
|
||||||
<div><button class="ant-btn" type="button" ant-click-animating-without-extra-node="false">
|
<div><button class="ant-btn" type="button" ant-click-animating-without-extra-node="false">
|
||||||
<!----><span>open</span>
|
<!----><span>open</span>
|
||||||
</button>
|
</button>
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-right" tabindex="-1">
|
<div tabindex="-1" class="ant-drawer ant-drawer-right">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
|
@ -20,6 +20,7 @@ exports[`Drawer render correctly 1`] = `
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -39,8 +39,8 @@ exports[`renders ./components/drawer/demo/render-in-current.vue correctly 1`] =
|
||||||
<div style="height: 200px; overflow: hidden; position: relative; border: 1px solid #ebedf0; border-radius: 2px; padding: 48px; text-align: center; background: rgb(250, 250, 250); width: 100%;"> Render in this <div style="margin-top: 16px;"><button class="ant-btn ant-btn-primary" type="button">
|
<div style="height: 200px; overflow: hidden; position: relative; border: 1px solid #ebedf0; border-radius: 2px; padding: 48px; text-align: center; background: rgb(250, 250, 250); width: 100%;"> Render in this <div style="margin-top: 16px;"><button class="ant-btn ant-btn-primary" type="button">
|
||||||
<!----><span>Open</span>
|
<!----><span>Open</span>
|
||||||
</button></div>
|
</button></div>
|
||||||
<div>
|
<div class="">
|
||||||
<div class="ant-drawer ant-drawer-right" tabindex="-1" style="position: absolute;">
|
<div tabindex="-1" class="ant-drawer ant-drawer-right" style="position: absolute;">
|
||||||
<div class="ant-drawer-mask"></div>
|
<div class="ant-drawer-mask"></div>
|
||||||
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
<div class="ant-drawer-content-wrapper" style="transform: translateX(100%); width: 378px;">
|
||||||
<div class="ant-drawer-content">
|
<div class="ant-drawer-content">
|
||||||
|
@ -58,6 +58,7 @@ exports[`renders ./components/drawer/demo/render-in-current.vue correctly 1`] =
|
||||||
<!---->
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!---->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,6 +20,8 @@ Basic drawer.
|
||||||
<a-button type="primary" @click="showDrawer">Open</a-button>
|
<a-button type="primary" @click="showDrawer">Open</a-button>
|
||||||
<a-drawer
|
<a-drawer
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
|
class="custom-class"
|
||||||
|
style="color: red"
|
||||||
title="Basic Drawer"
|
title="Basic Drawer"
|
||||||
placement="right"
|
placement="right"
|
||||||
@after-visible-change="afterVisibleChange"
|
@after-visible-change="afterVisibleChange"
|
||||||
|
|
|
@ -21,7 +21,7 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| autoFocus | Whether Drawer should get focused after open | boolean | true | 3.0.0 |
|
| autoFocus | Whether Drawer should get focused after open | boolean | true | 3.0.0 |
|
||||||
| bodyStyle | Style of the drawer content part | CSSProperties | - | |
|
| bodyStyle | Style of the drawer content part | CSSProperties | - | |
|
||||||
| className(old: wrapClassName) | The class name of the container of the Drawer dialog | string | - | 3.0.0 |
|
| class | The class name of the container of the Drawer dialog | string | - | |
|
||||||
| closable | Whether a close (x) button is visible on top right of the Drawer dialog or not | boolean | true | |
|
| closable | Whether a close (x) button is visible on top right of the Drawer dialog or not | boolean | true | |
|
||||||
| closeIcon | Custom close icon | VNode \| slot | <CloseOutlined /> | 3.0.0 |
|
| closeIcon | Custom close icon | VNode \| slot | <CloseOutlined /> | 3.0.0 |
|
||||||
| contentWrapperStyle | Style of the drawer wrapper of content part | CSSProperties | 3.0.0 |
|
| contentWrapperStyle | Style of the drawer wrapper of content part | CSSProperties | 3.0.0 |
|
||||||
|
@ -41,7 +41,7 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
||||||
| placement | The placement of the Drawer | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | |
|
| placement | The placement of the Drawer | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | |
|
||||||
| push | Nested drawers push behavior | boolean \| {distance: string \| number} | { distance: 180} | 3.0.0 |
|
| push | Nested drawers push behavior | boolean \| {distance: string \| number} | { distance: 180} | 3.0.0 |
|
||||||
| size | presetted size of drawer, default `378px` and large `736px` | `default` \| `large` | `default` | 3.0.0 |
|
| size | presetted size of drawer, default `378px` and large `736px` | `default` \| `large` | `default` | 3.0.0 |
|
||||||
| style(old: wrapStyle) | Style of wrapper element which contains mask compare to drawerStyle | CSSProperties | - | 3.0.0 |
|
| style | Style of wrapper element which contains mask compare to drawerStyle | CSSProperties | - | |
|
||||||
| title | The title for Drawer | string \| slot | - | |
|
| title | The title for Drawer | string \| slot | - | |
|
||||||
| visible(v-model) | Whether the Drawer dialog is visible or not | boolean | - | |
|
| visible(v-model) | Whether the Drawer dialog is visible or not | boolean | - | |
|
||||||
| width | Width of the Drawer dialog | string \| number | 378 | |
|
| width | Width of the Drawer dialog | string \| number | 378 | |
|
||||||
|
|
|
@ -6,11 +6,11 @@ import {
|
||||||
ref,
|
ref,
|
||||||
onMounted,
|
onMounted,
|
||||||
provide,
|
provide,
|
||||||
onBeforeMount,
|
|
||||||
onUpdated,
|
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
|
watch,
|
||||||
|
computed,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { getPropsSlot } from '../_util/props-util';
|
import { getPropsSlot, initDefaultProps } from '../_util/props-util';
|
||||||
import classnames from '../_util/classNames';
|
import classnames from '../_util/classNames';
|
||||||
import VcDrawer from '../vc-drawer';
|
import VcDrawer from '../vc-drawer';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
|
@ -18,6 +18,7 @@ import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
|
||||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
import { tuple, withInstall } from '../_util/type';
|
import { tuple, withInstall } from '../_util/type';
|
||||||
import omit from '../_util/omit';
|
import omit from '../_util/omit';
|
||||||
|
import devWarning from '../vc-util/devWarning';
|
||||||
|
|
||||||
const PlacementTypes = tuple('top', 'right', 'bottom', 'left');
|
const PlacementTypes = tuple('top', 'right', 'bottom', 'left');
|
||||||
export type placementType = typeof PlacementTypes[number];
|
export type placementType = typeof PlacementTypes[number];
|
||||||
|
@ -31,17 +32,22 @@ export interface PushState {
|
||||||
|
|
||||||
const defaultPushState: PushState = { distance: 180 };
|
const defaultPushState: PushState = { distance: 180 };
|
||||||
|
|
||||||
const drawerProps = {
|
const drawerProps = () => ({
|
||||||
autoFocus: PropTypes.looseBool,
|
autofocus: PropTypes.looseBool,
|
||||||
closable: PropTypes.looseBool.def(true),
|
closable: PropTypes.looseBool,
|
||||||
closeIcon: PropTypes.VNodeChild.def(<CloseOutlined />),
|
closeIcon: PropTypes.VNodeChild,
|
||||||
destroyOnClose: PropTypes.looseBool,
|
destroyOnClose: PropTypes.looseBool,
|
||||||
forceRender: PropTypes.looseBool,
|
forceRender: PropTypes.looseBool,
|
||||||
getContainer: PropTypes.any,
|
getContainer: PropTypes.any,
|
||||||
maskClosable: PropTypes.looseBool.def(true),
|
maskClosable: PropTypes.looseBool,
|
||||||
mask: PropTypes.looseBool.def(true),
|
mask: PropTypes.looseBool,
|
||||||
maskStyle: PropTypes.object,
|
maskStyle: PropTypes.object,
|
||||||
style: PropTypes.object,
|
/** @deprecated Use `style` instead */
|
||||||
|
wrapStyle: PropTypes.style,
|
||||||
|
style: PropTypes.style,
|
||||||
|
class: PropTypes.any,
|
||||||
|
/** @deprecated Use `class` instead */
|
||||||
|
wrapClassName: PropTypes.string,
|
||||||
size: {
|
size: {
|
||||||
type: String as PropType<sizeType>,
|
type: String as PropType<sizeType>,
|
||||||
},
|
},
|
||||||
|
@ -50,44 +56,74 @@ const drawerProps = {
|
||||||
bodyStyle: PropTypes.object,
|
bodyStyle: PropTypes.object,
|
||||||
contentWrapperStyle: PropTypes.object,
|
contentWrapperStyle: PropTypes.object,
|
||||||
title: PropTypes.VNodeChild,
|
title: PropTypes.VNodeChild,
|
||||||
visible: PropTypes.looseBool,
|
visible: PropTypes.looseBool.isRequired,
|
||||||
className: PropTypes.string,
|
|
||||||
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
zIndex: PropTypes.number,
|
zIndex: PropTypes.number,
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
push: PropTypes.oneOfType([PropTypes.looseBool, { type: Object as PropType<PushState> }]).def(
|
push: PropTypes.oneOfType([PropTypes.looseBool, { type: Object as PropType<PushState> }]),
|
||||||
defaultPushState,
|
placement: PropTypes.oneOf(PlacementTypes),
|
||||||
),
|
keyboard: PropTypes.looseBool,
|
||||||
placement: PropTypes.oneOf(PlacementTypes).def('right'),
|
|
||||||
keyboard: PropTypes.looseBool.def(true),
|
|
||||||
extra: PropTypes.VNodeChild,
|
extra: PropTypes.VNodeChild,
|
||||||
footer: PropTypes.VNodeChild,
|
footer: PropTypes.VNodeChild,
|
||||||
footerStyle: PropTypes.object,
|
footerStyle: PropTypes.object,
|
||||||
level: PropTypes.any.def(null),
|
level: PropTypes.any,
|
||||||
levelMove: PropTypes.any,
|
levelMove: PropTypes.any,
|
||||||
};
|
handle: PropTypes.VNodeChild,
|
||||||
|
/** @deprecated Use `@afterVisibleChange` instead */
|
||||||
|
afterVisibleChange: PropTypes.func,
|
||||||
|
});
|
||||||
|
|
||||||
export type DrawerProps = Partial<ExtractPropTypes<typeof drawerProps>>;
|
export type DrawerProps = Partial<ExtractPropTypes<typeof drawerProps>>;
|
||||||
|
|
||||||
const Drawer = defineComponent({
|
const Drawer = defineComponent({
|
||||||
name: 'ADrawer',
|
name: 'ADrawer',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: drawerProps,
|
props: initDefaultProps(drawerProps(), {
|
||||||
|
closable: true,
|
||||||
|
placement: 'right' as placementType,
|
||||||
|
maskClosable: true,
|
||||||
|
mask: true,
|
||||||
|
level: null,
|
||||||
|
keyboard: true,
|
||||||
|
push: defaultPushState,
|
||||||
|
}),
|
||||||
|
slots: ['closeIcon', 'title', 'extra', 'footer', 'handle'],
|
||||||
emits: ['update:visible', 'close', 'afterVisibleChange'],
|
emits: ['update:visible', 'close', 'afterVisibleChange'],
|
||||||
setup(props, { emit, slots, attrs }) {
|
setup(props, { emit, slots, attrs }) {
|
||||||
const sPush = ref(false);
|
const sPush = ref(false);
|
||||||
const preVisible = ref(props.visible);
|
|
||||||
const destroyClose = ref(false);
|
const destroyClose = ref(false);
|
||||||
const vcDrawer = ref(null);
|
const vcDrawer = ref(null);
|
||||||
const parentDrawerOpts = inject('parentDrawerOpts', null);
|
const parentDrawerOpts = inject('parentDrawerOpts', null);
|
||||||
const { prefixCls } = useConfigInject('drawer', props);
|
const { prefixCls } = useConfigInject('drawer', props);
|
||||||
|
devWarning(
|
||||||
|
!props.afterVisibleChange,
|
||||||
|
'Drawer',
|
||||||
|
'`afterVisibleChange` prop is deprecated, please use `@afterVisibleChange` event instead',
|
||||||
|
);
|
||||||
|
devWarning(
|
||||||
|
props.wrapStyle === undefined,
|
||||||
|
'Drawer',
|
||||||
|
'`wrapStyle` prop is deprecated, please use `style` instead',
|
||||||
|
);
|
||||||
|
devWarning(
|
||||||
|
props.wrapClassName === undefined,
|
||||||
|
'Drawer',
|
||||||
|
'`wrapClassName` prop is deprecated, please use `class` instead',
|
||||||
|
);
|
||||||
|
const setPush = () => {
|
||||||
|
sPush.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
onBeforeMount(() => {
|
const setPull = () => {
|
||||||
provide('parentDrawerOpts', {
|
sPush.value = false;
|
||||||
setPush,
|
nextTick(() => {
|
||||||
setPull,
|
domFocus();
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
provide('parentDrawerOpts', {
|
||||||
|
setPush,
|
||||||
|
setPull,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -103,19 +139,19 @@ const Drawer = defineComponent({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onUpdated(() => {
|
watch(
|
||||||
const { visible } = props;
|
() => props.visible,
|
||||||
nextTick(() => {
|
visible => {
|
||||||
if (preVisible.value !== visible && parentDrawerOpts) {
|
if (parentDrawerOpts) {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
parentDrawerOpts.setPush();
|
parentDrawerOpts.setPush();
|
||||||
} else {
|
} else {
|
||||||
parentDrawerOpts.setPull();
|
parentDrawerOpts.setPull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
preVisible.value = visible;
|
},
|
||||||
});
|
{ flush: 'post' },
|
||||||
});
|
);
|
||||||
|
|
||||||
const domFocus = () => {
|
const domFocus = () => {
|
||||||
vcDrawer.value?.domFocus?.();
|
vcDrawer.value?.domFocus?.();
|
||||||
|
@ -127,22 +163,12 @@ const Drawer = defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const afterVisibleChange = (visible: boolean) => {
|
const afterVisibleChange = (visible: boolean) => {
|
||||||
|
props.afterVisibleChange?.(visible);
|
||||||
emit('afterVisibleChange', visible);
|
emit('afterVisibleChange', visible);
|
||||||
};
|
};
|
||||||
|
const destroyOnClose = computed(() => props.destroyOnClose && !props.visible);
|
||||||
const setPush = () => {
|
|
||||||
sPush.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const setPull = () => {
|
|
||||||
sPush.value = false;
|
|
||||||
nextTick(() => {
|
|
||||||
domFocus();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDestroyTransitionEnd = () => {
|
const onDestroyTransitionEnd = () => {
|
||||||
const isDestroyOnClose = getDestroyOnClose();
|
const isDestroyOnClose = destroyOnClose.value;
|
||||||
if (!isDestroyOnClose) {
|
if (!isDestroyOnClose) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -151,12 +177,8 @@ const Drawer = defineComponent({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDestroyOnClose = () => {
|
const pushTransform = computed(() => {
|
||||||
return props.destroyOnClose && !props.visible;
|
const { push, placement } = props;
|
||||||
};
|
|
||||||
|
|
||||||
const getPushTransform = (placement?: placementType) => {
|
|
||||||
const { push } = props;
|
|
||||||
let distance: number | string;
|
let distance: number | string;
|
||||||
if (typeof push === 'boolean') {
|
if (typeof push === 'boolean') {
|
||||||
distance = push ? defaultPushState.distance : 0;
|
distance = push ? defaultPushState.distance : 0;
|
||||||
|
@ -172,18 +194,39 @@ const Drawer = defineComponent({
|
||||||
if (placement === 'top' || placement === 'bottom') {
|
if (placement === 'top' || placement === 'bottom') {
|
||||||
return `translateY(${placement === 'top' ? distance : -distance}px)`;
|
return `translateY(${placement === 'top' ? distance : -distance}px)`;
|
||||||
}
|
}
|
||||||
};
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
const getRcDrawerStyle = () => {
|
const offsetStyle = computed(() => {
|
||||||
const { zIndex, placement, style, mask } = props;
|
// https://github.com/ant-design/ant-design/issues/24287
|
||||||
const offsetStyle = mask ? {} : getOffsetStyle();
|
const { visible, mask, placement, size, width, height } = props;
|
||||||
|
if (!visible && !mask) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const val: CSSProperties = {};
|
||||||
|
if (placement === 'left' || placement === 'right') {
|
||||||
|
const defaultWidth = size === 'large' ? 736 : 378;
|
||||||
|
val.width = typeof width === 'undefined' ? defaultWidth : width;
|
||||||
|
val.width = typeof val.width === 'string' ? val.width : `${val.width}px`;
|
||||||
|
} else {
|
||||||
|
const defaultHeight = size === 'large' ? 736 : 378;
|
||||||
|
val.height = typeof height === 'undefined' ? defaultHeight : height;
|
||||||
|
val.height = typeof val.height === 'string' ? val.height : `${val.height}px`;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
|
||||||
|
const drawerStyle = computed(() => {
|
||||||
|
const { zIndex, wrapStyle, mask, style } = props;
|
||||||
|
const val = mask ? {} : offsetStyle.value;
|
||||||
return {
|
return {
|
||||||
zIndex,
|
zIndex,
|
||||||
transform: sPush.value ? getPushTransform(placement) : undefined,
|
transform: sPush.value ? pushTransform.value : undefined,
|
||||||
...offsetStyle,
|
...val,
|
||||||
|
...wrapStyle,
|
||||||
...style,
|
...style,
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
|
|
||||||
const renderHeader = (prefixCls: string) => {
|
const renderHeader = (prefixCls: string) => {
|
||||||
const { closable, headerStyle } = props;
|
const { closable, headerStyle } = props;
|
||||||
|
@ -211,11 +254,11 @@ const Drawer = defineComponent({
|
||||||
|
|
||||||
const renderCloseIcon = (prefixCls: string) => {
|
const renderCloseIcon = (prefixCls: string) => {
|
||||||
const { closable } = props;
|
const { closable } = props;
|
||||||
const $closeIcon = getPropsSlot(slots, props, 'closeIcon');
|
const $closeIcon = props.closeIcon ? slots.closeIcon?.() : props.closeIcon;
|
||||||
return (
|
return (
|
||||||
closable && (
|
closable && (
|
||||||
<button key="closer" onClick={close} aria-label="Close" class={`${prefixCls}-close`}>
|
<button key="closer" onClick={close} aria-label="Close" class={`${prefixCls}-close`}>
|
||||||
{$closeIcon}
|
{$closeIcon === undefined ? <CloseOutlined></CloseOutlined> : null}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -231,7 +274,7 @@ const Drawer = defineComponent({
|
||||||
|
|
||||||
const containerStyle: CSSProperties = {};
|
const containerStyle: CSSProperties = {};
|
||||||
|
|
||||||
const isDestroyOnClose = getDestroyOnClose();
|
const isDestroyOnClose = destroyOnClose.value;
|
||||||
if (isDestroyOnClose) {
|
if (isDestroyOnClose) {
|
||||||
// Increase the opacity transition, delete children after closing.
|
// Increase the opacity transition, delete children after closing.
|
||||||
containerStyle.opacity = 0;
|
containerStyle.opacity = 0;
|
||||||
|
@ -267,27 +310,19 @@ const Drawer = defineComponent({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOffsetStyle = () => {
|
|
||||||
// https://github.com/ant-design/ant-design/issues/24287
|
|
||||||
const { visible, mask, placement, size, width, height } = props;
|
|
||||||
if (!visible && !mask) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const offsetStyle: CSSProperties = {};
|
|
||||||
if (placement === 'left' || placement === 'right') {
|
|
||||||
const defaultWidth = size === 'large' ? 736 : 378;
|
|
||||||
offsetStyle.width = typeof width === 'undefined' ? defaultWidth : width;
|
|
||||||
} else {
|
|
||||||
const defaultHeight = size === 'large' ? 736 : 378;
|
|
||||||
offsetStyle.height = typeof height === 'undefined' ? defaultHeight : height;
|
|
||||||
}
|
|
||||||
return offsetStyle;
|
|
||||||
};
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const { width, height, visible, placement, mask, className, ...rest } = props;
|
const {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
visible,
|
||||||
|
placement,
|
||||||
|
mask,
|
||||||
|
wrapClassName,
|
||||||
|
class: className,
|
||||||
|
...rest
|
||||||
|
} = props;
|
||||||
|
|
||||||
const offsetStyle = mask ? getOffsetStyle() : {};
|
const val = mask ? offsetStyle.value : {};
|
||||||
const haveMask = mask ? '' : 'no-mask';
|
const haveMask = mask ? '' : 'no-mask';
|
||||||
const vcDrawerProps: any = {
|
const vcDrawerProps: any = {
|
||||||
...attrs,
|
...attrs,
|
||||||
|
@ -301,8 +336,9 @@ const Drawer = defineComponent({
|
||||||
'bodyStyle',
|
'bodyStyle',
|
||||||
'title',
|
'title',
|
||||||
'push',
|
'push',
|
||||||
|
'wrapStyle',
|
||||||
]),
|
]),
|
||||||
...offsetStyle,
|
...val,
|
||||||
onClose: close,
|
onClose: close,
|
||||||
afterVisibleChange,
|
afterVisibleChange,
|
||||||
handler: false,
|
handler: false,
|
||||||
|
@ -310,14 +346,23 @@ const Drawer = defineComponent({
|
||||||
open: visible,
|
open: visible,
|
||||||
showMask: mask,
|
showMask: mask,
|
||||||
placement,
|
placement,
|
||||||
wrapperClassName: classnames({
|
class: classnames({
|
||||||
[className as string]: className,
|
[className]: className,
|
||||||
|
[wrapClassName]: !!wrapClassName,
|
||||||
[haveMask]: !!haveMask,
|
[haveMask]: !!haveMask,
|
||||||
}),
|
}),
|
||||||
style: getRcDrawerStyle(),
|
style: drawerStyle.value,
|
||||||
ref: vcDrawer,
|
ref: vcDrawer,
|
||||||
};
|
};
|
||||||
return <VcDrawer {...vcDrawerProps}>{renderBody(prefixCls.value)}</VcDrawer>;
|
return (
|
||||||
|
<VcDrawer
|
||||||
|
{...vcDrawerProps}
|
||||||
|
v-slots={{
|
||||||
|
handler: props.handle ? () => props.handle : slots.handle,
|
||||||
|
default: () => renderBody(prefixCls.value),
|
||||||
|
}}
|
||||||
|
></VcDrawer>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/7z8NJQhFb/Drawer.svg
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| autoFocus | 抽屉展开后是否将焦点切换至其 Dom 节点 | boolean | true | 3.0.0 |
|
| autoFocus | 抽屉展开后是否将焦点切换至其 Dom 节点 | boolean | true | 3.0.0 |
|
||||||
| bodyStyle | 可用于设置 Drawer 内容部分的样式 | CSSProperties | - | |
|
| bodyStyle | 可用于设置 Drawer 内容部分的样式 | CSSProperties | - | |
|
||||||
| className(原 wrapClassName) | 对话框外层容器的类名 | string | - | 3.0.0 |
|
| class | 对话框外层容器的类名 | string | - | |
|
||||||
| closable | 是否显示右上角的关闭按钮 | boolean | true | |
|
| closable | 是否显示右上角的关闭按钮 | boolean | true | |
|
||||||
| closeIcon | 自定义关闭图标 | VNode \| slot | <CloseOutlined /> | 3.0.0 |
|
| closeIcon | 自定义关闭图标 | VNode \| slot | <CloseOutlined /> | 3.0.0 |
|
||||||
| contentWrapperStyle | 可用于设置 Drawer 包裹内容部分的样式 | CSSProperties | 3.0.0 |
|
| contentWrapperStyle | 可用于设置 Drawer 包裹内容部分的样式 | CSSProperties | 3.0.0 |
|
||||||
|
@ -41,7 +41,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/7z8NJQhFb/Drawer.svg
|
||||||
| placement | 抽屉的方向 | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | |
|
| placement | 抽屉的方向 | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | |
|
||||||
| push | 用于设置多层 Drawer 的推动行为 | boolean \| {distance: string \| number} | { distance: 180} | 3.0.0 |
|
| push | 用于设置多层 Drawer 的推动行为 | boolean \| {distance: string \| number} | { distance: 180} | 3.0.0 |
|
||||||
| size | 预设抽屉宽度(或高度),default `378px` 和 large `736px` | `default` \| `large` | `default` | 3.0.0 |
|
| size | 预设抽屉宽度(或高度),default `378px` 和 large `736px` | `default` \| `large` | `default` | 3.0.0 |
|
||||||
| style(原 wrapStyle) | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | CSSProperties | - | 3.0.0 |
|
| style | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | CSSProperties | - | |
|
||||||
| title | 标题 | string \| slot | - | |
|
| title | 标题 | string \| slot | - | |
|
||||||
| visible(v-model) | Drawer 是否可见 | boolean | - | |
|
| visible(v-model) | Drawer 是否可见 | boolean | - | |
|
||||||
| width | 宽度 | string \| number | 378 | |
|
| width | 宽度 | string \| number | 378 | |
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../style/themes/index.less';
|
@import '../../style/themes/index';
|
||||||
|
|
||||||
@drawer-prefix-cls: ~'@{ant-prefix}-drawer';
|
@drawer-prefix-cls: ~'@{ant-prefix}-drawer';
|
||||||
@picker-prefix-cls: ~'@{ant-prefix}-picker';
|
@picker-prefix-cls: ~'@{ant-prefix}-picker';
|
||||||
|
@ -237,6 +237,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =================== Hook Components ===================
|
||||||
.@{picker-prefix-cls} {
|
.@{picker-prefix-cls} {
|
||||||
&-clear {
|
&-clear {
|
||||||
background: @popover-background;
|
background: @popover-background;
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
@import './drawer';
|
@import './drawer';
|
||||||
@import './rtl';
|
@import './rtl';
|
||||||
|
|
||||||
// .popover-customize-bg(@drawer-prefix-cls, @popover-background);
|
.popover-customize-bg(@drawer-prefix-cls, @popover-background);
|
||||||
|
|
|
@ -458,7 +458,7 @@ exports[`renders ./components/menu/demo/vertical.vue correctly 1`] = `
|
||||||
<li class="ant-menu-submenu ant-menu-submenu-vertical" role="none" data-submenu-id="sub2">
|
<li class="ant-menu-submenu ant-menu-submenu-vertical" role="none" data-submenu-id="sub2">
|
||||||
<!--teleport start-->
|
<!--teleport start-->
|
||||||
<!--teleport end-->
|
<!--teleport end-->
|
||||||
<div class="ant-menu-submenu-title" tabindex="-1" data-menu-id="sub2" aria-expanded="false" aria-haspopup="true" aria-controls="sub_menu_23_$$_sub2-popup" aria-disabled="false"><span role="img" aria-label="setting" class="anticon anticon-setting ant-menu-item-icon"><svg focusable="false" class="" data-icon="setting" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"></path></svg></span><span class="ant-menu-title-content">Navigation Four</span><i class="ant-menu-submenu-arrow"></i></div>
|
<div class="ant-menu-submenu-title" tabindex="-1" data-menu-id="sub2" aria-expanded="false" aria-haspopup="true" aria-controls="sub_menu_24_$$_sub2-popup" aria-disabled="false"><span role="img" aria-label="setting" class="anticon anticon-setting ant-menu-item-icon"><svg focusable="false" class="" data-icon="setting" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"></path></svg></span><span class="ant-menu-title-content">Navigation Four</span><i class="ant-menu-submenu-arrow"></i></div>
|
||||||
<!---->
|
<!---->
|
||||||
</li>
|
</li>
|
||||||
<!---->
|
<!---->
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils';
|
||||||
import Modal from '..';
|
import Modal from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import { asyncExpect } from '../../../tests/utils';
|
import { asyncExpect } from '../../../tests/utils';
|
||||||
|
jest.mock('../../_util/Portal');
|
||||||
const ModalTester = {
|
const ModalTester = {
|
||||||
props: ['footer', 'visible'],
|
props: ['footer', 'visible'],
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -2,88 +2,73 @@
|
||||||
|
|
||||||
exports[`Modal render correctly 1`] = `
|
exports[`Modal render correctly 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div></div>
|
||||||
<div>
|
<div class="ant-modal-root">
|
||||||
<div class="ant-modal-root">
|
<div class="ant-modal-mask"></div>
|
||||||
<div class="ant-modal-mask"></div>
|
<div tabindex="-1" class="ant-modal-wrap " role="dialog">
|
||||||
<div tabindex="-1" class="ant-modal-wrap " role="dialog">
|
<div role="document" style="width: 520px;" class="ant-modal">
|
||||||
<div role="document" style="width: 520px;" class="ant-modal">
|
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
||||||
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
<div class="ant-modal-content"><button type="button" aria-label="Close" class="ant-modal-close"><span class="ant-modal-close-x"><span role="img" aria-label="close" class="anticon anticon-close ant-modal-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></button>
|
||||||
<div class="ant-modal-content"><button type="button" aria-label="Close" class="ant-modal-close"><span class="ant-modal-close-x"><span role="img" aria-label="close" class="anticon anticon-close ant-modal-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></button>
|
<!---->
|
||||||
<!---->
|
<div class="ant-modal-body">Here is content of Modal</div>
|
||||||
<div class="ant-modal-body">Here is content of Modal</div>
|
<div class="ant-modal-footer">
|
||||||
<div class="ant-modal-footer">
|
<div><button class="ant-btn" type="button">
|
||||||
<div><button class="ant-btn" type="button">
|
<!----><span>Cancel</span>
|
||||||
<!----><span>Cancel</span>
|
</button><button class="ant-btn ant-btn-primary" type="button">
|
||||||
</button><button class="ant-btn ant-btn-primary" type="button">
|
<!----><span>OK</span>
|
||||||
<!----><span>OK</span>
|
</button></div>
|
||||||
</button></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--teleport start-->
|
|
||||||
<!--teleport end-->
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Modal render correctly 2`] = `
|
exports[`Modal render correctly 2`] = `
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div></div>
|
||||||
<div>
|
<div class="ant-modal-root">
|
||||||
<div class="ant-modal-root">
|
<div class="ant-modal-mask"></div>
|
||||||
<div class="ant-modal-mask"></div>
|
<div tabindex="-1" class="ant-modal-wrap " role="dialog">
|
||||||
<div tabindex="-1" class="ant-modal-wrap " role="dialog">
|
<div role="document" style="width: 520px;" class="ant-modal">
|
||||||
<div role="document" style="width: 520px;" class="ant-modal">
|
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
||||||
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
<div class="ant-modal-content"><button type="button" aria-label="Close" class="ant-modal-close"><span class="ant-modal-close-x"><span role="img" aria-label="close" class="anticon anticon-close ant-modal-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></button>
|
||||||
<div class="ant-modal-content"><button type="button" aria-label="Close" class="ant-modal-close"><span class="ant-modal-close-x"><span role="img" aria-label="close" class="anticon anticon-close ant-modal-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></button>
|
<!---->
|
||||||
<!---->
|
<div class="ant-modal-body">Here is content of Modal</div>
|
||||||
<div class="ant-modal-body">Here is content of Modal</div>
|
<div class="ant-modal-footer">
|
||||||
<div class="ant-modal-footer">
|
<div><button class="ant-btn" type="button">
|
||||||
<div><button class="ant-btn" type="button">
|
<!----><span>Cancel</span>
|
||||||
<!----><span>Cancel</span>
|
</button><button class="ant-btn ant-btn-primary" type="button">
|
||||||
</button><button class="ant-btn ant-btn-primary" type="button">
|
<!----><span>OK</span>
|
||||||
<!----><span>OK</span>
|
</button></div>
|
||||||
</button></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--teleport start-->
|
|
||||||
<!--teleport end-->
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Modal render without footer 1`] = `
|
exports[`Modal render without footer 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div></div>
|
||||||
<div>
|
<div class="ant-modal-root">
|
||||||
<div class="ant-modal-root">
|
<div class="ant-modal-mask"></div>
|
||||||
<div class="ant-modal-mask"></div>
|
<div tabindex="-1" class="ant-modal-wrap " role="dialog">
|
||||||
<div tabindex="-1" class="ant-modal-wrap " role="dialog">
|
<div role="document" style="width: 520px;" class="ant-modal">
|
||||||
<div role="document" style="width: 520px;" class="ant-modal">
|
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
||||||
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
<div class="ant-modal-content"><button type="button" aria-label="Close" class="ant-modal-close"><span class="ant-modal-close-x"><span role="img" aria-label="close" class="anticon anticon-close ant-modal-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></button>
|
||||||
<div class="ant-modal-content"><button type="button" aria-label="Close" class="ant-modal-close"><span class="ant-modal-close-x"><span role="img" aria-label="close" class="anticon anticon-close ant-modal-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></button>
|
<!---->
|
||||||
<!---->
|
<div class="ant-modal-body">Here is content of Modal</div>
|
||||||
<div class="ant-modal-body">Here is content of Modal</div>
|
<!---->
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div tabindex="0" style="width: 0px; height: 0px; overflow: hidden;" aria-hidden="true"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--teleport start-->
|
|
||||||
<!--teleport end-->
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Modal from '..';
|
import Modal from '..';
|
||||||
import { sleep } from '../../../tests/utils';
|
import { sleep } from '../../../tests/utils';
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
jest.mock('../../_util/Portal');
|
||||||
|
|
||||||
describe('Modal.confirm triggers callbacks correctly', () => {
|
describe('Modal.confirm triggers callbacks correctly', () => {
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
@ -8,6 +9,7 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
errorSpy.mockReset();
|
errorSpy.mockReset();
|
||||||
document.body.innerHTML = '';
|
document.body.innerHTML = '';
|
||||||
|
Modal.destroyAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
@ -19,11 +21,14 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function open(args) {
|
function open(args) {
|
||||||
|
jest.useFakeTimers();
|
||||||
confirm({
|
confirm({
|
||||||
title: 'Want to delete these items?',
|
title: 'Want to delete these items?',
|
||||||
content: 'some descriptions',
|
content: 'some descriptions',
|
||||||
...args,
|
...args,
|
||||||
});
|
});
|
||||||
|
jest.runAllTimers();
|
||||||
|
jest.useRealTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
it('trigger onCancel once when click on cancel button', async () => {
|
it('trigger onCancel once when click on cancel button', async () => {
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
// customize dark components background in popover containers(like Modal, Drawer, Card, Popover, Popconfirm, Notification, ...)
|
||||||
|
// for dark theme
|
||||||
|
.popover-customize-bg(@containerClass, @background: @popover-background, @prefix: @ant-prefix)
|
||||||
|
when
|
||||||
|
(@theme = dark) {
|
||||||
|
@picker-prefix-cls: ~'@{prefix}-picker';
|
||||||
|
@slider-prefix-cls: ~'@{prefix}-slider';
|
||||||
|
@anchor-prefix-cls: ~'@{prefix}-anchor';
|
||||||
|
@collapse-prefix-cls: ~'@{prefix}-collapse';
|
||||||
|
@tab-prefix-cls: ~'@{prefix}-tabs';
|
||||||
|
@timeline-prefix-cls: ~'@{prefix}-timeline';
|
||||||
|
@tree-prefix-cls: ~'@{prefix}-tree';
|
||||||
|
@card-prefix-cls: ~'@{prefix}-card';
|
||||||
|
@badge-prefix-cls: ~'@{prefix}-badge';
|
||||||
|
@transfer-prefix-cls: ~'@{prefix}-transfer';
|
||||||
|
@calendar-prefix-cls: ~'@{prefix}-picker-calendar';
|
||||||
|
@calendar-picker-prefix-cls: ~'@{prefix}-picker';
|
||||||
|
@table-prefix-cls: ~'@{prefix}-table';
|
||||||
|
|
||||||
|
@popover-border: @border-width-base @border-style-base @popover-customize-border-color;
|
||||||
|
|
||||||
|
.@{containerClass} {
|
||||||
|
.@{picker-prefix-cls}-clear,
|
||||||
|
.@{slider-prefix-cls}-handle,
|
||||||
|
.@{anchor-prefix-cls}-wrapper,
|
||||||
|
.@{collapse-prefix-cls}-content,
|
||||||
|
.@{timeline-prefix-cls}-item-head,
|
||||||
|
.@{card-prefix-cls} {
|
||||||
|
background-color: @background;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{transfer-prefix-cls} {
|
||||||
|
&-list {
|
||||||
|
&-header {
|
||||||
|
background: @background;
|
||||||
|
border-bottom: @popover-border;
|
||||||
|
}
|
||||||
|
&-content-item:not(.@{transfer-prefix-cls}-list-content-item-disabled):hover {
|
||||||
|
background-color: @item-hover-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.@{table-prefix-cls}-expanded-row {
|
||||||
|
&,
|
||||||
|
&:hover {
|
||||||
|
> td {
|
||||||
|
background: #272727;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.@{table-prefix-cls}.@{table-prefix-cls}-small {
|
||||||
|
thead {
|
||||||
|
> tr {
|
||||||
|
> th {
|
||||||
|
background-color: @background;
|
||||||
|
border-bottom: @popover-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.@{table-prefix-cls} {
|
||||||
|
background-color: @background;
|
||||||
|
.@{table-prefix-cls}-row-expand-icon {
|
||||||
|
border: @popover-border;
|
||||||
|
}
|
||||||
|
tfoot {
|
||||||
|
> tr {
|
||||||
|
> th,
|
||||||
|
> td {
|
||||||
|
border-bottom: @popover-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thead {
|
||||||
|
> tr {
|
||||||
|
> th {
|
||||||
|
background-color: #272727;
|
||||||
|
border-bottom: @popover-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tbody {
|
||||||
|
> tr {
|
||||||
|
> td {
|
||||||
|
border-bottom: @popover-border;
|
||||||
|
&.@{table-prefix-cls}-cell-fix-left,
|
||||||
|
&.@{table-prefix-cls}-cell-fix-right {
|
||||||
|
background-color: @background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.@{table-prefix-cls}-row:hover {
|
||||||
|
> td {
|
||||||
|
background: @table-header-sort-active-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.@{table-prefix-cls}-bordered {
|
||||||
|
.@{table-prefix-cls}-title {
|
||||||
|
border: @popover-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================= Cell =============================
|
||||||
|
thead > tr > th,
|
||||||
|
tbody > tr > td,
|
||||||
|
tfoot > tr > th,
|
||||||
|
tfoot > tr > td {
|
||||||
|
border-right: @popover-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixed right should provides additional border
|
||||||
|
.@{table-prefix-cls}-cell-fix-right-first::after {
|
||||||
|
border-right: @popover-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================ Header ============================
|
||||||
|
table > {
|
||||||
|
thead {
|
||||||
|
> tr:not(:last-child) > th {
|
||||||
|
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================== Content ============================
|
||||||
|
.@{table-prefix-cls}-container {
|
||||||
|
border: @popover-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================== Expandable ==========================
|
||||||
|
.@{table-prefix-cls}-expanded-row-fixed {
|
||||||
|
&::after {
|
||||||
|
border-right: @popover-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{table-prefix-cls}-footer {
|
||||||
|
border: @popover-border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.@{table-prefix-cls}-filter-trigger-container-open {
|
||||||
|
background-color: #525252;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{calendar-prefix-cls}-full {
|
||||||
|
background-color: @background;
|
||||||
|
.@{calendar-picker-prefix-cls}-panel {
|
||||||
|
background-color: @background;
|
||||||
|
.@{calendar-prefix-cls}-date {
|
||||||
|
border-top: 2px solid @popover-customize-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{tab-prefix-cls} {
|
||||||
|
&.@{tab-prefix-cls}-card .@{tab-prefix-cls}-card-bar .@{tab-prefix-cls}-tab-active {
|
||||||
|
background-color: @background;
|
||||||
|
border-bottom: @border-width-base solid @background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{badge-prefix-cls} {
|
||||||
|
&-count {
|
||||||
|
box-shadow: 0 0 0 1px @background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{tree-prefix-cls} {
|
||||||
|
&-show-line {
|
||||||
|
.@{tree-prefix-cls}-switcher {
|
||||||
|
background: @background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,5 +8,6 @@
|
||||||
@import 'reset';
|
@import 'reset';
|
||||||
@import 'operation-unit';
|
@import 'operation-unit';
|
||||||
@import 'typography';
|
@import 'typography';
|
||||||
|
@import 'customize';
|
||||||
@import 'box';
|
@import 'box';
|
||||||
@import 'modal-mask';
|
@import 'modal-mask';
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import { asyncExpect, sleep } from '../../../tests/utils';
|
import { asyncExpect, sleep } from '../../../tests/utils';
|
||||||
import Table from '..';
|
import Table from '..';
|
||||||
|
jest.mock('../../_util/Portal');
|
||||||
describe('Table.rowSelection', () => {
|
describe('Table.rowSelection', () => {
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
errorSpy.mockReset();
|
errorSpy.mockReset();
|
||||||
|
document.body.innerHTML = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
@ -582,8 +583,9 @@ describe('Table.rowSelection', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check Lucy
|
// Check Lucy
|
||||||
clickFilter([0, 1]);
|
clickFilter([0]);
|
||||||
|
await sleep();
|
||||||
|
clickFilter([1]);
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(wrapper.findAll('tbody tr').length).toBe(1);
|
expect(wrapper.findAll('tbody tr').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// base rc-drawer 4.4.2
|
||||||
import Drawer from './src/DrawerWrapper';
|
import Drawer from './src/DrawerWrapper';
|
||||||
|
|
||||||
export default Drawer;
|
export default Drawer;
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
import { defineComponent, reactive, onMounted, onUpdated, onUnmounted, nextTick, watch } from 'vue';
|
import {
|
||||||
|
defineComponent,
|
||||||
|
reactive,
|
||||||
|
onMounted,
|
||||||
|
computed,
|
||||||
|
onUnmounted,
|
||||||
|
nextTick,
|
||||||
|
watch,
|
||||||
|
ref,
|
||||||
|
} from 'vue';
|
||||||
import classnames from '../../_util/classNames';
|
import classnames from '../../_util/classNames';
|
||||||
import getScrollBarSize from '../../_util/getScrollBarSize';
|
import getScrollBarSize from '../../_util/getScrollBarSize';
|
||||||
import KeyCode from '../../_util/KeyCode';
|
import KeyCode from '../../_util/KeyCode';
|
||||||
import omit from '../../_util/omit';
|
import omit from '../../_util/omit';
|
||||||
import supportsPassive from '../../_util/supportsPassive';
|
import supportsPassive from '../../_util/supportsPassive';
|
||||||
import { DrawerChildProps } from './IDrawerPropTypes';
|
import { drawerChildProps } from './IDrawerPropTypes';
|
||||||
import type { IDrawerChildProps } from './IDrawerPropTypes';
|
|
||||||
import setStyle from '../../_util/setStyle';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
addEventListener,
|
addEventListener,
|
||||||
|
@ -25,127 +32,92 @@ export interface scrollLockOptions {
|
||||||
container: HTMLElement;
|
container: HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createScrollLocker = (options: scrollLockOptions) => {
|
|
||||||
const scrollBarSize = 0;
|
|
||||||
const cacheStyleMap = new Map();
|
|
||||||
return {
|
|
||||||
getContainer: () => {
|
|
||||||
return options?.container;
|
|
||||||
},
|
|
||||||
getCacheStyleMap: () => {
|
|
||||||
return cacheStyleMap;
|
|
||||||
},
|
|
||||||
lock: () => {
|
|
||||||
cacheStyleMap.set(
|
|
||||||
options.container,
|
|
||||||
setStyle(
|
|
||||||
{
|
|
||||||
width: scrollBarSize !== 0 ? `calc(100% - ${scrollBarSize}px)` : undefined,
|
|
||||||
overflow: 'hidden',
|
|
||||||
overflowX: 'hidden',
|
|
||||||
overflowY: 'hidden',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
element: options.container || document.body,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
unLock: () => {
|
|
||||||
setStyle(cacheStyleMap.get(options.container) || {}, { element: options.container });
|
|
||||||
cacheStyleMap.delete(options.container);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const DrawerChild = defineComponent({
|
const DrawerChild = defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: DrawerChildProps,
|
props: drawerChildProps(),
|
||||||
emits: ['close', 'handleClick', 'change'],
|
emits: ['close', 'handleClick', 'change'],
|
||||||
setup(props, { emit, slots }) {
|
setup(props, { emit, slots }) {
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
levelDom: [],
|
|
||||||
dom: null,
|
|
||||||
contentWrapper: null,
|
|
||||||
contentDom: null,
|
|
||||||
maskDom: null,
|
|
||||||
handlerDom: null,
|
|
||||||
drawerId: null,
|
|
||||||
timeout: null,
|
|
||||||
passive: null,
|
|
||||||
startPos: {
|
startPos: {
|
||||||
x: null,
|
x: null,
|
||||||
y: null,
|
y: null,
|
||||||
},
|
},
|
||||||
scrollLocker: null,
|
|
||||||
});
|
});
|
||||||
|
let timeout;
|
||||||
|
const contentWrapper = ref<HTMLElement>();
|
||||||
|
const dom = ref<HTMLElement>();
|
||||||
|
const maskDom = ref<HTMLElement>();
|
||||||
|
const handlerDom = ref<HTMLElement>();
|
||||||
|
const contentDom = ref<HTMLElement>();
|
||||||
|
let levelDom = [];
|
||||||
|
const drawerId = `drawer_id_${Number(
|
||||||
|
(Date.now() + Math.random())
|
||||||
|
.toString()
|
||||||
|
.replace('.', Math.round(Math.random() * 9).toString()),
|
||||||
|
).toString(16)}`;
|
||||||
|
|
||||||
|
const passive = !windowIsUndefined && supportsPassive ? { passive: false } : false;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (!windowIsUndefined) {
|
const { open, getContainer, showMask, autofocus } = props;
|
||||||
state.passive = supportsPassive ? { passive: false } : false;
|
|
||||||
}
|
|
||||||
const { open, getContainer, showMask, autoFocus } = props;
|
|
||||||
const container = getContainer?.();
|
const container = getContainer?.();
|
||||||
state.drawerId = `drawer_id_${Number(
|
|
||||||
(Date.now() + Math.random())
|
|
||||||
.toString()
|
|
||||||
.replace('.', Math.round(Math.random() * 9).toString()),
|
|
||||||
).toString(16)}`;
|
|
||||||
getLevelDom(props);
|
getLevelDom(props);
|
||||||
|
|
||||||
if (container) {
|
|
||||||
state.scrollLocker = createScrollLocker({
|
|
||||||
container: container.parentNode,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
if (container && container.parentNode === document.body) {
|
if (container && container.parentNode === document.body) {
|
||||||
currentDrawer[state.drawerId] = open;
|
currentDrawer[drawerId] = open;
|
||||||
}
|
}
|
||||||
// 默认打开状态时推出 level;
|
// 默认打开状态时推出 level;
|
||||||
openLevelTransition();
|
openLevelTransition();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (autoFocus) {
|
if (autofocus) {
|
||||||
domFocus();
|
domFocus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (showMask) {
|
if (showMask) {
|
||||||
state.scrollLocker?.lock();
|
props.scrollLocker?.lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
watch(
|
||||||
onUpdated(() => {
|
() => props.level,
|
||||||
const { open, getContainer, showMask, autoFocus } = props;
|
() => {
|
||||||
|
getLevelDom(props);
|
||||||
const container = getContainer?.();
|
},
|
||||||
if (container && container.parentNode === document.body) {
|
{ flush: 'post' },
|
||||||
currentDrawer[state.drawerId] = !!open;
|
);
|
||||||
}
|
watch(
|
||||||
openLevelTransition();
|
() => props.open,
|
||||||
if (open) {
|
() => {
|
||||||
if (autoFocus) {
|
const { open, getContainer, scrollLocker, showMask, autofocus } = props;
|
||||||
domFocus();
|
const container = getContainer?.();
|
||||||
|
if (container && container.parentNode === document.body) {
|
||||||
|
currentDrawer[drawerId] = !!open;
|
||||||
}
|
}
|
||||||
if (showMask) {
|
openLevelTransition();
|
||||||
state.scrollLocker?.lock();
|
if (open) {
|
||||||
|
if (autofocus) {
|
||||||
|
domFocus();
|
||||||
|
}
|
||||||
|
if (showMask) {
|
||||||
|
scrollLocker?.lock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scrollLocker?.unLock();
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
state.scrollLocker?.unLock();
|
{ flush: 'post' },
|
||||||
}
|
);
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
const { open } = props;
|
const { open } = props;
|
||||||
delete currentDrawer[state.drawerId];
|
delete currentDrawer[drawerId];
|
||||||
if (open) {
|
if (open) {
|
||||||
setLevelTransform(false);
|
setLevelTransform(false);
|
||||||
document.body.style.touchAction = '';
|
document.body.style.touchAction = '';
|
||||||
}
|
}
|
||||||
state.scrollLocker?.unLock();
|
props.scrollLocker?.unLock();
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -153,19 +125,13 @@ const DrawerChild = defineComponent({
|
||||||
val => {
|
val => {
|
||||||
if (val) {
|
if (val) {
|
||||||
// test 的 bug, 有动画过场,删除 dom
|
// test 的 bug, 有动画过场,删除 dom
|
||||||
state.contentDom = null;
|
contentDom.value = null;
|
||||||
if (state.contentWrapper) {
|
|
||||||
state.contentWrapper.style.transition = `none`;
|
|
||||||
setTimeout(() => {
|
|
||||||
state.contentWrapper.style.transition = ``;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const domFocus = () => {
|
const domFocus = () => {
|
||||||
state.dom?.focus?.();
|
dom.value?.focus?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeStartHandler = (e: TouchEvent) => {
|
const removeStartHandler = (e: TouchEvent) => {
|
||||||
|
@ -186,9 +152,9 @@ const DrawerChild = defineComponent({
|
||||||
const differX = e.changedTouches[0].clientX - state.startPos.x;
|
const differX = e.changedTouches[0].clientX - state.startPos.x;
|
||||||
const differY = e.changedTouches[0].clientY - state.startPos.y;
|
const differY = e.changedTouches[0].clientY - state.startPos.y;
|
||||||
if (
|
if (
|
||||||
(currentTarget === state.maskDom ||
|
(currentTarget === maskDom.value ||
|
||||||
currentTarget === state.handlerDom ||
|
currentTarget === handlerDom.value ||
|
||||||
(currentTarget === state.contentDom &&
|
(currentTarget === contentDom.value &&
|
||||||
getTouchParentScroll(currentTarget, e.target as HTMLElement, differX, differY))) &&
|
getTouchParentScroll(currentTarget, e.target as HTMLElement, differX, differY))) &&
|
||||||
e.cancelable
|
e.cancelable
|
||||||
) {
|
) {
|
||||||
|
@ -201,6 +167,9 @@ const DrawerChild = defineComponent({
|
||||||
removeEventListener(dom, transitionEndFun, transitionEnd);
|
removeEventListener(dom, transitionEndFun, transitionEnd);
|
||||||
dom.style.transition = '';
|
dom.style.transition = '';
|
||||||
};
|
};
|
||||||
|
const onClose = (e: Event) => {
|
||||||
|
emit('close', e);
|
||||||
|
};
|
||||||
|
|
||||||
const onKeyDown = (e: KeyboardEvent) => {
|
const onKeyDown = (e: KeyboardEvent) => {
|
||||||
if (e.keyCode === KeyCode.ESC) {
|
if (e.keyCode === KeyCode.ESC) {
|
||||||
|
@ -209,19 +178,15 @@ const DrawerChild = defineComponent({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClose = (e: Event) => {
|
|
||||||
emit('close', e);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onWrapperTransitionEnd = (e: TransitionEvent) => {
|
const onWrapperTransitionEnd = (e: TransitionEvent) => {
|
||||||
const { open, afterVisibleChange } = props;
|
const { open, afterVisibleChange } = props;
|
||||||
if (e.target === state.contentWrapper && e.propertyName.match(/transform$/)) {
|
if (e.target === contentWrapper.value && e.propertyName.match(/transform$/)) {
|
||||||
state.dom.style.transition = '';
|
dom.value.style.transition = '';
|
||||||
if (!open && getCurrentDrawerSome()) {
|
if (!open && getCurrentDrawerSome()) {
|
||||||
document.body.style.overflowX = '';
|
document.body.style.overflowX = '';
|
||||||
if (state.maskDom) {
|
if (maskDom.value) {
|
||||||
state.maskDom.style.left = '';
|
maskDom.value.style.left = '';
|
||||||
state.maskDom.style.width = '';
|
maskDom.value.style.width = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (afterVisibleChange) {
|
if (afterVisibleChange) {
|
||||||
|
@ -230,11 +195,21 @@ const DrawerChild = defineComponent({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const horizontalBoolAndPlacementName = computed(() => {
|
||||||
|
const { placement } = props;
|
||||||
|
const isHorizontal = placement === 'left' || placement === 'right';
|
||||||
|
const placementName = `translate${isHorizontal ? 'X' : 'Y'}`;
|
||||||
|
return {
|
||||||
|
isHorizontal,
|
||||||
|
placementName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const openLevelTransition = () => {
|
const openLevelTransition = () => {
|
||||||
const { open, width, height } = props;
|
const { open, width, height } = props;
|
||||||
const { isHorizontal, placementName } = getHorizontalBoolAndPlacementName();
|
const { isHorizontal, placementName } = horizontalBoolAndPlacementName.value;
|
||||||
const contentValue = state.contentDom
|
const contentValue = contentDom.value
|
||||||
? state.contentDom.getBoundingClientRect()[isHorizontal ? 'width' : 'height']
|
? contentDom.value.getBoundingClientRect()[isHorizontal ? 'width' : 'height']
|
||||||
: 0;
|
: 0;
|
||||||
const value = (isHorizontal ? width : height) || contentValue;
|
const value = (isHorizontal ? width : height) || contentValue;
|
||||||
setLevelAndScrolling(open, placementName, value);
|
setLevelAndScrolling(open, placementName, value);
|
||||||
|
@ -248,7 +223,7 @@ const DrawerChild = defineComponent({
|
||||||
) => {
|
) => {
|
||||||
const { placement, levelMove, duration, ease, showMask } = props;
|
const { placement, levelMove, duration, ease, showMask } = props;
|
||||||
// router 切换时可能会导至页面失去滚动条,所以需要时时获取。
|
// router 切换时可能会导至页面失去滚动条,所以需要时时获取。
|
||||||
state.levelDom.forEach(dom => {
|
levelDom.forEach(dom => {
|
||||||
dom.style.transition = `transform ${duration} ${ease}`;
|
dom.style.transition = `transform ${duration} ${ease}`;
|
||||||
addEventListener(dom, transitionEndFun, transitionEnd);
|
addEventListener(dom, transitionEndFun, transitionEnd);
|
||||||
let levelValue = open ? value : 0;
|
let levelValue = open ? value : 0;
|
||||||
|
@ -290,7 +265,7 @@ const DrawerChild = defineComponent({
|
||||||
// 处理 body 滚动
|
// 处理 body 滚动
|
||||||
if (container && container.parentNode === document.body && showMask) {
|
if (container && container.parentNode === document.body && showMask) {
|
||||||
const eventArray = ['touchstart'];
|
const eventArray = ['touchstart'];
|
||||||
const domArray = [document.body, state.maskDom, state.handlerDom, state.contentDom];
|
const domArray = [document.body, maskDom.value, handlerDom.value, contentDom.value];
|
||||||
if (open && document.body.style.overflow !== 'hidden') {
|
if (open && document.body.style.overflow !== 'hidden') {
|
||||||
if (right) {
|
if (right) {
|
||||||
addScrollingEffect(right);
|
addScrollingEffect(right);
|
||||||
|
@ -305,7 +280,7 @@ const DrawerChild = defineComponent({
|
||||||
item,
|
item,
|
||||||
eventArray[i] || 'touchmove',
|
eventArray[i] || 'touchmove',
|
||||||
i ? removeMoveHandler : removeStartHandler,
|
i ? removeMoveHandler : removeStartHandler,
|
||||||
state.passive,
|
passive,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else if (getCurrentDrawerSome()) {
|
} else if (getCurrentDrawerSome()) {
|
||||||
|
@ -322,7 +297,7 @@ const DrawerChild = defineComponent({
|
||||||
item,
|
item,
|
||||||
eventArray[i] || 'touchmove',
|
eventArray[i] || 'touchmove',
|
||||||
i ? removeMoveHandler : removeStartHandler,
|
i ? removeMoveHandler : removeStartHandler,
|
||||||
state.passive,
|
passive,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -333,25 +308,25 @@ const DrawerChild = defineComponent({
|
||||||
const { placement, duration, ease } = props;
|
const { placement, duration, ease } = props;
|
||||||
const widthTransition = `width ${duration} ${ease}`;
|
const widthTransition = `width ${duration} ${ease}`;
|
||||||
const transformTransition = `transform ${duration} ${ease}`;
|
const transformTransition = `transform ${duration} ${ease}`;
|
||||||
state.dom.style.transition = 'none';
|
dom.value.style.transition = 'none';
|
||||||
switch (placement) {
|
switch (placement) {
|
||||||
case 'right':
|
case 'right':
|
||||||
state.dom.style.transform = `translateX(-${right}px)`;
|
dom.value.style.transform = `translateX(-${right}px)`;
|
||||||
break;
|
break;
|
||||||
case 'top':
|
case 'top':
|
||||||
case 'bottom':
|
case 'bottom':
|
||||||
state.dom.style.width = `calc(100% - ${right}px)`;
|
dom.value.style.width = `calc(100% - ${right}px)`;
|
||||||
state.dom.style.transform = 'translateZ(0)';
|
dom.value.style.transform = 'translateZ(0)';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
clearTimeout(state.timeout);
|
clearTimeout(timeout);
|
||||||
state.timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
if (state.dom) {
|
if (dom.value) {
|
||||||
state.dom.style.transition = `${transformTransition},${widthTransition}`;
|
dom.value.style.transition = `${transformTransition},${widthTransition}`;
|
||||||
state.dom.style.width = '';
|
dom.value.style.width = '';
|
||||||
state.dom.style.transform = '';
|
dom.value.style.transform = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -359,59 +334,59 @@ const DrawerChild = defineComponent({
|
||||||
const remScrollingEffect = (right: number) => {
|
const remScrollingEffect = (right: number) => {
|
||||||
const { placement, duration, ease } = props;
|
const { placement, duration, ease } = props;
|
||||||
|
|
||||||
state.dom.style.transition = 'none';
|
dom.value.style.transition = 'none';
|
||||||
let heightTransition: string;
|
let heightTransition: string;
|
||||||
let widthTransition = `width ${duration} ${ease}`;
|
let widthTransition = `width ${duration} ${ease}`;
|
||||||
const transformTransition = `transform ${duration} ${ease}`;
|
const transformTransition = `transform ${duration} ${ease}`;
|
||||||
switch (placement) {
|
switch (placement) {
|
||||||
case 'left': {
|
case 'left': {
|
||||||
state.dom.style.width = '100%';
|
dom.value.style.width = '100%';
|
||||||
widthTransition = `width 0s ${ease} ${duration}`;
|
widthTransition = `width 0s ${ease} ${duration}`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'right': {
|
case 'right': {
|
||||||
state.dom.style.transform = `translateX(${right}px)`;
|
dom.value.style.transform = `translateX(${right}px)`;
|
||||||
state.dom.style.width = '100%';
|
dom.value.style.width = '100%';
|
||||||
widthTransition = `width 0s ${ease} ${duration}`;
|
widthTransition = `width 0s ${ease} ${duration}`;
|
||||||
if (state.maskDom) {
|
if (maskDom.value) {
|
||||||
state.maskDom.style.left = `-${right}px`;
|
maskDom.value.style.left = `-${right}px`;
|
||||||
state.maskDom.style.width = `calc(100% + ${right}px)`;
|
maskDom.value.style.width = `calc(100% + ${right}px)`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'top':
|
case 'top':
|
||||||
case 'bottom': {
|
case 'bottom': {
|
||||||
state.dom.style.width = `calc(100% + ${right}px)`;
|
dom.value.style.width = `calc(100% + ${right}px)`;
|
||||||
state.dom.style.height = '100%';
|
dom.value.style.height = '100%';
|
||||||
state.dom.style.transform = 'translateZ(0)';
|
dom.value.style.transform = 'translateZ(0)';
|
||||||
heightTransition = `height 0s ${ease} ${duration}`;
|
heightTransition = `height 0s ${ease} ${duration}`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
clearTimeout(state.timeout);
|
clearTimeout(timeout);
|
||||||
state.timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
if (state.dom) {
|
if (dom.value) {
|
||||||
state.dom.style.transition = `${transformTransition},${
|
dom.value.style.transition = `${transformTransition},${
|
||||||
heightTransition ? `${heightTransition},` : ''
|
heightTransition ? `${heightTransition},` : ''
|
||||||
}${widthTransition}`;
|
}${widthTransition}`;
|
||||||
state.dom.style.transform = '';
|
dom.value.style.transform = '';
|
||||||
state.dom.style.width = '';
|
dom.value.style.width = '';
|
||||||
state.dom.style.height = '';
|
dom.value.style.height = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCurrentDrawerSome = () => !Object.keys(currentDrawer).some(key => currentDrawer[key]);
|
const getCurrentDrawerSome = () => !Object.keys(currentDrawer).some(key => currentDrawer[key]);
|
||||||
|
|
||||||
const getLevelDom = ({ level, getContainer }: IDrawerChildProps) => {
|
const getLevelDom = ({ level, getContainer }) => {
|
||||||
if (windowIsUndefined) {
|
if (windowIsUndefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const container = getContainer?.();
|
const container = getContainer?.();
|
||||||
const parent = container ? (container.parentNode as HTMLElement) : null;
|
const parent = container ? (container.parentNode as HTMLElement) : null;
|
||||||
state.levelDom = [];
|
levelDom = [];
|
||||||
if (level === 'all') {
|
if (level === 'all') {
|
||||||
const children: HTMLElement[] = parent ? Array.prototype.slice.call(parent.children) : [];
|
const children: HTMLElement[] = parent ? Array.prototype.slice.call(parent.children) : [];
|
||||||
children.forEach((child: HTMLElement) => {
|
children.forEach((child: HTMLElement) => {
|
||||||
|
@ -421,28 +396,28 @@ const DrawerChild = defineComponent({
|
||||||
child.nodeName !== 'LINK' &&
|
child.nodeName !== 'LINK' &&
|
||||||
child !== container
|
child !== container
|
||||||
) {
|
) {
|
||||||
state.levelDom.push(child);
|
levelDom.push(child);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (level) {
|
} else if (level) {
|
||||||
dataToArray(level).forEach(key => {
|
dataToArray(level).forEach(key => {
|
||||||
document.querySelectorAll(key).forEach(item => {
|
document.querySelectorAll(key).forEach(item => {
|
||||||
state.levelDom.push(item);
|
levelDom.push(item);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getHorizontalBoolAndPlacementName = () => {
|
const onHandleClick = e => {
|
||||||
const { placement } = props;
|
emit('handleClick', e);
|
||||||
const isHorizontal = placement === 'left' || placement === 'right';
|
|
||||||
const placementName = `translate${isHorizontal ? 'X' : 'Y'}`;
|
|
||||||
return {
|
|
||||||
isHorizontal,
|
|
||||||
placementName,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const canOpen = ref(false);
|
||||||
|
watch(dom, () => {
|
||||||
|
nextTick(() => {
|
||||||
|
canOpen.value = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
return () => {
|
return () => {
|
||||||
const {
|
const {
|
||||||
width,
|
width,
|
||||||
|
@ -465,17 +440,19 @@ const DrawerChild = defineComponent({
|
||||||
scrollLocker,
|
scrollLocker,
|
||||||
contentWrapperStyle,
|
contentWrapperStyle,
|
||||||
style,
|
style,
|
||||||
|
class: className,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
// 首次渲染都将是关闭状态。
|
// 首次渲染都将是关闭状态。
|
||||||
const open = state.dom ? $open : false;
|
const open = $open && canOpen.value;
|
||||||
const wrapperClassName = classnames(prefixCls, {
|
const wrapperClassName = classnames(prefixCls, {
|
||||||
[`${prefixCls}-${placement}`]: true,
|
[`${prefixCls}-${placement}`]: true,
|
||||||
[`${prefixCls}-open`]: open,
|
[`${prefixCls}-open`]: open,
|
||||||
|
[className]: !!className,
|
||||||
'no-mask': !showMask,
|
'no-mask': !showMask,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { placementName } = getHorizontalBoolAndPlacementName();
|
const { placementName } = horizontalBoolAndPlacementName.value;
|
||||||
// 百分比与像素动画不同步,第一次打用后全用像素动画。
|
// 百分比与像素动画不同步,第一次打用后全用像素动画。
|
||||||
// const defaultValue = !this.contentDom || !level ? '100%' : `${value}px`;
|
// const defaultValue = !this.contentDom || !level ? '100%' : `${value}px`;
|
||||||
const placementPos = placement === 'left' || placement === 'top' ? '-100%' : '100%';
|
const placementPos = placement === 'left' || placement === 'top' ? '-100%' : '100%';
|
||||||
|
@ -483,13 +460,11 @@ const DrawerChild = defineComponent({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
{...omit(otherProps, ['switchScrollingEffect', 'autoFocus'])}
|
{...omit(otherProps, ['switchScrollingEffect', 'autofocus'])}
|
||||||
tabindex={-1}
|
tabindex={-1}
|
||||||
class={wrapperClassName}
|
class={wrapperClassName}
|
||||||
style={style}
|
style={style}
|
||||||
ref={(c: HTMLElement | null) => {
|
ref={dom}
|
||||||
state.dom = c as HTMLElement;
|
|
||||||
}}
|
|
||||||
onKeydown={open && keyboard ? onKeyDown : undefined}
|
onKeydown={open && keyboard ? onKeyDown : undefined}
|
||||||
onTransitionend={onWrapperTransitionEnd}
|
onTransitionend={onWrapperTransitionEnd}
|
||||||
>
|
>
|
||||||
|
@ -498,9 +473,7 @@ const DrawerChild = defineComponent({
|
||||||
class={`${prefixCls}-mask`}
|
class={`${prefixCls}-mask`}
|
||||||
onClick={maskClosable ? onClose : undefined}
|
onClick={maskClosable ? onClose : undefined}
|
||||||
style={maskStyle}
|
style={maskStyle}
|
||||||
ref={c => {
|
ref={maskDom}
|
||||||
state.maskDom = c as HTMLElement;
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
|
@ -512,18 +485,16 @@ const DrawerChild = defineComponent({
|
||||||
height: isNumeric(height) ? `${height}px` : height,
|
height: isNumeric(height) ? `${height}px` : height,
|
||||||
...contentWrapperStyle,
|
...contentWrapperStyle,
|
||||||
}}
|
}}
|
||||||
ref={c => {
|
ref={contentWrapper}
|
||||||
state.contentWrapper = c as HTMLElement;
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div
|
<div class={`${prefixCls}-content`} ref={contentDom}>
|
||||||
class={`${prefixCls}-content`}
|
{slots.default?.()}
|
||||||
ref={c => {
|
|
||||||
state.contentDom = c as HTMLElement;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{slots.children?.()}
|
|
||||||
</div>
|
</div>
|
||||||
|
{slots.handler ? (
|
||||||
|
<div onClick={onHandleClick} ref={handlerDom}>
|
||||||
|
{slots.handler?.()}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import Child from './DrawerChild';
|
import Child from './DrawerChild';
|
||||||
import { initDefaultProps } from '../../_util/props-util';
|
import { initDefaultProps } from '../../_util/props-util';
|
||||||
import { Teleport, defineComponent, ref, watch } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
import { DrawerProps } from './IDrawerPropTypes';
|
import { drawerProps } from './IDrawerPropTypes';
|
||||||
import type { IDrawerProps } from './IDrawerPropTypes';
|
import PortalWrapper from '../../_util/PortalWrapper';
|
||||||
|
|
||||||
const DrawerWrapper = defineComponent({
|
const DrawerWrapper = defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: initDefaultProps(DrawerProps, {
|
props: initDefaultProps(drawerProps(), {
|
||||||
prefixCls: 'drawer',
|
prefixCls: 'drawer',
|
||||||
placement: 'left',
|
placement: 'left',
|
||||||
getContainer: 'body',
|
getContainer: 'body',
|
||||||
|
@ -17,55 +17,16 @@ const DrawerWrapper = defineComponent({
|
||||||
showMask: true,
|
showMask: true,
|
||||||
maskClosable: true,
|
maskClosable: true,
|
||||||
maskStyle: {},
|
maskStyle: {},
|
||||||
wrapperClassName: null,
|
wrapperClassName: '',
|
||||||
keyboard: true,
|
keyboard: true,
|
||||||
forceRender: false,
|
forceRender: false,
|
||||||
autoFocus: true,
|
autofocus: true,
|
||||||
}),
|
}),
|
||||||
emits: ['handleClick', 'close'],
|
emits: ['handleClick', 'close'],
|
||||||
|
slots: ['handler'],
|
||||||
setup(props, { emit, expose, slots }) {
|
setup(props, { emit, slots }) {
|
||||||
const dom = ref<HTMLElement>(null);
|
const dom = ref<HTMLElement>(null);
|
||||||
|
|
||||||
const container = ref(props.getContainer || null);
|
|
||||||
|
|
||||||
const open = ref<boolean>(props.open);
|
|
||||||
|
|
||||||
const $forceRender = ref<boolean>(props.forceRender);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.open,
|
|
||||||
val => {
|
|
||||||
if (!dom.value) {
|
|
||||||
$forceRender.value = true;
|
|
||||||
open.value = false;
|
|
||||||
setTimeout(() => {
|
|
||||||
open.value = true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
open.value = val;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const getDerivedStateFromProps = (
|
|
||||||
props: IDrawerProps,
|
|
||||||
{ prevProps }: { prevProps: IDrawerProps },
|
|
||||||
) => {
|
|
||||||
const newState: {
|
|
||||||
open?: boolean;
|
|
||||||
prevProps: IDrawerProps;
|
|
||||||
} = {
|
|
||||||
prevProps: props,
|
|
||||||
};
|
|
||||||
if (typeof prevProps !== 'undefined' && props.open !== prevProps.open) {
|
|
||||||
newState.open = props.open;
|
|
||||||
}
|
|
||||||
return newState;
|
|
||||||
};
|
|
||||||
|
|
||||||
expose({ getDerivedStateFromProps });
|
|
||||||
|
|
||||||
const onHandleClick = (e: MouseEvent | KeyboardEvent) => {
|
const onHandleClick = (e: MouseEvent | KeyboardEvent) => {
|
||||||
emit('handleClick', e);
|
emit('handleClick', e);
|
||||||
};
|
};
|
||||||
|
@ -81,11 +42,11 @@ const DrawerWrapper = defineComponent({
|
||||||
let portal = null;
|
let portal = null;
|
||||||
if (!getContainer) {
|
if (!getContainer) {
|
||||||
return (
|
return (
|
||||||
<div class={wrapperClassName || null} ref={dom}>
|
<div class={wrapperClassName} ref={dom}>
|
||||||
<Child
|
<Child
|
||||||
v-slots={{ children: slots.default }}
|
v-slots={slots}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
open={open.value}
|
open={props.open}
|
||||||
getContainer={() => dom.value}
|
getContainer={() => dom.value}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onHandleClick={onHandleClick}
|
onHandleClick={onHandleClick}
|
||||||
|
@ -93,21 +54,33 @@ const DrawerWrapper = defineComponent({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($forceRender.value || open.value || dom.value) {
|
|
||||||
|
// 如果有 handler 为内置强制渲染;
|
||||||
|
const $forceRender = !!slots.handler || forceRender;
|
||||||
|
if ($forceRender || props.open || dom.value) {
|
||||||
portal = (
|
portal = (
|
||||||
<Teleport to={container.value}>
|
<PortalWrapper
|
||||||
<div class={wrapperClassName || null} ref={dom}>
|
visible={props.open}
|
||||||
<Child
|
forceRender={$forceRender}
|
||||||
v-slots={{ children: slots.default }}
|
getContainer={getContainer}
|
||||||
{...props}
|
wrapperClassName={wrapperClassName}
|
||||||
open={open.value}
|
v-slots={{
|
||||||
getContainer={() => dom.value}
|
default: ({ visible, afterClose, ...rest }) => (
|
||||||
afterVisibleChange={afterVisibleChange}
|
<Child
|
||||||
onClose={onClose}
|
ref={dom}
|
||||||
onHandleClick={onHandleClick}
|
v-slots={slots}
|
||||||
/>
|
{...otherProps}
|
||||||
</div>
|
{...rest}
|
||||||
</Teleport>
|
open={visible !== undefined ? visible : props.open}
|
||||||
|
afterVisibleChange={
|
||||||
|
afterClose !== undefined ? afterClose : props.afterVisibleChange
|
||||||
|
}
|
||||||
|
onClose={onClose}
|
||||||
|
onHandleClick={onHandleClick}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
></PortalWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return portal;
|
return portal;
|
||||||
|
|
|
@ -1,34 +1,38 @@
|
||||||
import PropTypes from '../../_util/vue-types';
|
import PropTypes from '../../_util/vue-types';
|
||||||
import type { PropType, ExtractPropTypes } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
export type IPlacement = 'left' | 'top' | 'right' | 'bottom';
|
export type IPlacement = 'left' | 'top' | 'right' | 'bottom';
|
||||||
|
type ILevelMove = number | [number, number];
|
||||||
const Props = {
|
const props = () => ({
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
style: PropTypes.object,
|
style: PropTypes.style,
|
||||||
|
class: PropTypes.string,
|
||||||
placement: {
|
placement: {
|
||||||
type: String as PropType<IPlacement>,
|
type: String as PropType<IPlacement>,
|
||||||
},
|
},
|
||||||
class: PropTypes.string,
|
wrapperClassName: PropTypes.string,
|
||||||
level: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
|
level: { type: [String, Array] as PropType<string | string[]> },
|
||||||
levelMove: PropTypes.oneOfType([PropTypes.number, PropTypes.func, PropTypes.array]),
|
levelMove: {
|
||||||
|
type: [Number, Function, Array] as PropType<
|
||||||
|
ILevelMove | ((e: { target: HTMLElement; open: boolean }) => ILevelMove)
|
||||||
|
>,
|
||||||
|
},
|
||||||
duration: PropTypes.string,
|
duration: PropTypes.string,
|
||||||
ease: PropTypes.string,
|
ease: PropTypes.string,
|
||||||
showMask: PropTypes.looseBool,
|
showMask: PropTypes.looseBool,
|
||||||
maskClosable: PropTypes.looseBool,
|
maskClosable: PropTypes.looseBool,
|
||||||
maskStyle: PropTypes.object,
|
maskStyle: PropTypes.style,
|
||||||
afterVisibleChange: PropTypes.func,
|
afterVisibleChange: PropTypes.func,
|
||||||
keyboard: PropTypes.looseBool,
|
keyboard: PropTypes.looseBool,
|
||||||
contentWrapperStyle: PropTypes.object,
|
contentWrapperStyle: PropTypes.style,
|
||||||
autoFocus: PropTypes.looseBool,
|
autofocus: PropTypes.looseBool,
|
||||||
open: PropTypes.looseBool,
|
open: PropTypes.looseBool,
|
||||||
};
|
});
|
||||||
|
|
||||||
const DrawerProps = {
|
const drawerProps = () => ({
|
||||||
...Props,
|
...props(),
|
||||||
wrapperClassName: PropTypes.string,
|
|
||||||
forceRender: PropTypes.looseBool,
|
forceRender: PropTypes.looseBool,
|
||||||
getContainer: PropTypes.oneOfType([
|
getContainer: PropTypes.oneOfType([
|
||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
|
@ -36,18 +40,14 @@ const DrawerProps = {
|
||||||
PropTypes.object,
|
PropTypes.object,
|
||||||
PropTypes.looseBool,
|
PropTypes.looseBool,
|
||||||
]),
|
]),
|
||||||
};
|
});
|
||||||
|
|
||||||
type IDrawerProps = Partial<ExtractPropTypes<typeof DrawerProps>>;
|
const drawerChildProps = () => ({
|
||||||
|
...props(),
|
||||||
const DrawerChildProps = {
|
|
||||||
...Props,
|
|
||||||
getContainer: PropTypes.func,
|
getContainer: PropTypes.func,
|
||||||
getOpenCount: PropTypes.func,
|
getOpenCount: PropTypes.func,
|
||||||
scrollLocker: PropTypes.any,
|
scrollLocker: PropTypes.any,
|
||||||
switchScrollingEffect: PropTypes.func,
|
switchScrollingEffect: PropTypes.func,
|
||||||
};
|
});
|
||||||
|
|
||||||
type IDrawerChildProps = Partial<ExtractPropTypes<typeof DrawerChildProps>>;
|
export { drawerProps, drawerChildProps };
|
||||||
|
|
||||||
export { DrawerProps, DrawerChildProps, IDrawerProps, IDrawerChildProps };
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { nextTick, onBeforeUnmount, ref, watch } from 'vue';
|
import { nextTick, onBeforeUnmount, ref, watch, onMounted } from 'vue';
|
||||||
import raf from '../../_util/raf';
|
import raf from '../../_util/raf';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,29 +62,32 @@ export default (
|
||||||
},
|
},
|
||||||
{ immediate: true, flush: 'post' },
|
{ immediate: true, flush: 'post' },
|
||||||
);
|
);
|
||||||
// Go next status
|
onMounted(() => {
|
||||||
watch(
|
// Go next status
|
||||||
status,
|
watch(
|
||||||
() => {
|
status,
|
||||||
switch (status.value) {
|
() => {
|
||||||
case 'measure':
|
switch (status.value) {
|
||||||
doMeasure();
|
case 'measure':
|
||||||
break;
|
doMeasure();
|
||||||
default:
|
break;
|
||||||
}
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.value) {
|
||||||
|
nextTick(() => {
|
||||||
|
const index = StatusQueue.indexOf(status.value);
|
||||||
|
const nextStatus = StatusQueue[index + 1];
|
||||||
|
if (nextStatus && index !== -1) {
|
||||||
|
setStatus(nextStatus);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true, flush: 'post' },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
if (status.value) {
|
|
||||||
nextTick(() => {
|
|
||||||
const index = StatusQueue.indexOf(status.value);
|
|
||||||
const nextStatus = StatusQueue[index + 1];
|
|
||||||
if (nextStatus && index !== -1) {
|
|
||||||
setStatus(nextStatus);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true, flush: 'post' },
|
|
||||||
);
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
destroyRef.value = true;
|
destroyRef.value = true;
|
||||||
cancelRaf();
|
cancelRaf();
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
import type { CSSProperties } from '@vue/runtime-dom';
|
||||||
|
import getScrollBarSize from '../../_util/getScrollBarSize';
|
||||||
|
import setStyle from '../../_util/setStyle';
|
||||||
|
|
||||||
|
export interface scrollLockOptions {
|
||||||
|
container: HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Ilocks {
|
||||||
|
target: typeof uuid;
|
||||||
|
options: scrollLockOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
let locks: Ilocks[] = [];
|
||||||
|
const scrollingEffectClassName = 'ant-scrolling-effect';
|
||||||
|
const scrollingEffectClassNameReg = new RegExp(`${scrollingEffectClassName}`, 'g');
|
||||||
|
|
||||||
|
let uuid = 0;
|
||||||
|
|
||||||
|
// https://github.com/ant-design/ant-design/issues/19340
|
||||||
|
// https://github.com/ant-design/ant-design/issues/19332
|
||||||
|
const cacheStyle = new Map<Element, CSSProperties>();
|
||||||
|
|
||||||
|
export default class ScrollLocker {
|
||||||
|
private lockTarget: typeof uuid;
|
||||||
|
|
||||||
|
private options: scrollLockOptions;
|
||||||
|
|
||||||
|
constructor(options?: scrollLockOptions) {
|
||||||
|
// eslint-disable-next-line no-plusplus
|
||||||
|
this.lockTarget = uuid++;
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
getContainer = (): HTMLElement | undefined => {
|
||||||
|
return this.options?.container;
|
||||||
|
};
|
||||||
|
|
||||||
|
// if options change...
|
||||||
|
reLock = (options?: scrollLockOptions) => {
|
||||||
|
const findLock = locks.find(({ target }) => target === this.lockTarget);
|
||||||
|
|
||||||
|
if (findLock) {
|
||||||
|
this.unLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
if (findLock) {
|
||||||
|
findLock.options = options;
|
||||||
|
this.lock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
lock = () => {
|
||||||
|
// If lockTarget exist return
|
||||||
|
if (locks.some(({ target }) => target === this.lockTarget)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If same container effect, return
|
||||||
|
if (locks.some(({ options }) => options?.container === this.options?.container)) {
|
||||||
|
locks = [...locks, { target: this.lockTarget, options: this.options }];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let scrollBarSize = 0;
|
||||||
|
const container = this.options?.container || document.body;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(container === document.body &&
|
||||||
|
window.innerWidth - document.documentElement.clientWidth > 0) ||
|
||||||
|
container.scrollHeight > container.clientHeight
|
||||||
|
) {
|
||||||
|
scrollBarSize = getScrollBarSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerClassName = container.className;
|
||||||
|
|
||||||
|
if (
|
||||||
|
locks.filter(({ options }) => options?.container === this.options?.container).length === 0
|
||||||
|
) {
|
||||||
|
cacheStyle.set(
|
||||||
|
container,
|
||||||
|
setStyle(
|
||||||
|
{
|
||||||
|
width: scrollBarSize !== 0 ? `calc(100% - ${scrollBarSize}px)` : undefined,
|
||||||
|
overflow: 'hidden',
|
||||||
|
overflowX: 'hidden',
|
||||||
|
overflowY: 'hidden',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: container,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/ant-design/ant-design/issues/19729
|
||||||
|
if (!scrollingEffectClassNameReg.test(containerClassName)) {
|
||||||
|
const addClassName = `${containerClassName} ${scrollingEffectClassName}`;
|
||||||
|
container.className = addClassName.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
locks = [...locks, { target: this.lockTarget, options: this.options }];
|
||||||
|
};
|
||||||
|
|
||||||
|
unLock = () => {
|
||||||
|
const findLock = locks.find(({ target }) => target === this.lockTarget);
|
||||||
|
|
||||||
|
locks = locks.filter(({ target }) => target !== this.lockTarget);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!findLock ||
|
||||||
|
locks.some(({ options }) => options?.container === findLock.options?.container)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Effect
|
||||||
|
const container = this.options?.container || document.body;
|
||||||
|
const containerClassName = container.className;
|
||||||
|
|
||||||
|
if (!scrollingEffectClassNameReg.test(containerClassName)) return;
|
||||||
|
|
||||||
|
setStyle(cacheStyle.get(container), { element: container });
|
||||||
|
cacheStyle.delete(container);
|
||||||
|
container.className = container.className.replace(scrollingEffectClassNameReg, '').trim();
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue