diff --git a/components/dialog/index.spec.ts b/components/dialog/index.spec.ts
index 38e0e8c3c..bec4d1e02 100644
--- a/components/dialog/index.spec.ts
+++ b/components/dialog/index.spec.ts
@@ -337,6 +337,36 @@ describe('Dialog', () => {
expect(dialog2.querySelector('.k-dialog-body')!.textContent).to.eql('test');
});
+ it('should update position when change container', async () => {
+ class Demo extends Component<{show: boolean, container: any}> {
+ static template = `
+ var Dialog = this.Dialog;
+
+ `;
+
+ private Dialog = Dialog;
+
+ static defaults() {
+ return {
+ container: (parentDom: HTMLElement) => parentDom,
+ };
+ }
+ }
+
+ const [instance, element] = mount(Demo);
+
+ await wait();
+ instance.set('container', undefined);
+ await wait();
+ const dialogDom = instance.refs.dialog.dialogRef.value;
+ const style = dialogDom.style;
+ expect(style.left).not.eql('');
+ expect(style.top).not.eql('');
+
+ // should append to body
+ expect(dialogDom.closest('.k-dialog-wrapper').parentElement).to.eql(document.body);
+ });
+
// it('should handle v-if and v-model at the same time correctly in Vue', async () => {
// const Test = {
// template: ``,
diff --git a/components/dialog/usePosition.ts b/components/dialog/usePosition.ts
index 278ff29d3..3b7296b2a 100644
--- a/components/dialog/usePosition.ts
+++ b/components/dialog/usePosition.ts
@@ -8,6 +8,10 @@ export function usePosition(elementRef: RefObject) {
instance.on(SHOW, center);
instance.on('afterClose', onAfterLeave);
+ instance.watch('container', () => {
+ if (!instance.get('value')) return;
+ center();
+ }, { presented: true, inited: true });
function center() {
position(elementRef.value!, {
diff --git a/components/dropdown/usePosition.ts b/components/dropdown/usePosition.ts
index d0d5b9db5..e2c1c0d40 100644
--- a/components/dropdown/usePosition.ts
+++ b/components/dropdown/usePosition.ts
@@ -1,8 +1,7 @@
import {useInstance, findDomFromVNode} from 'intact';
import type {Dropdown} from './';
import {Options, position, Feedback} from '../position';
-import {noop} from 'intact-shared';
-import {isObject} from 'intact-shared';
+import {noop, isObject, isFunction} from 'intact-shared';
import { isEqualObject } from '../utils';
export type FeedbackCallback = (feedback: Feedback) => void;
@@ -19,21 +18,32 @@ export function usePosition() {
(['of', 'position'] as const).forEach(item => {
instance.watch(item, (newValue, oldValue) => {
- // return if object is the same
if (
+ instance.get('value') ||
+ // return if object is the same
isObject(newValue) && isObject(oldValue) &&
// is not event object
!(newValue instanceof Event) &&
isEqualObject(newValue, oldValue)
- ) {
- return;
- }
- if (instance.get('value')) {
- handle(noop);
- }
+ ) return;
+
+ handle(noop);
}, {presented: true, inited: true});
});
+ // watch container, it is not commonly used
+ instance.watch('container', (newValue, oldValue) => {
+ if (
+ !instance.get('value') ||
+ // return if function is the same. Not rigorous!
+ isFunction(newValue) &&
+ isFunction(oldValue) &&
+ newValue.toString() === oldValue.toString()
+ ) return;
+
+ handle(noop);
+ }, { presented: true, inited: true });
+
// if the dropdown is nested, we must show child after parent has positioned
function p(
ofElement: HTMLElement | MouseEvent | undefined,
diff --git a/components/portal.ts b/components/portal.ts
index 6983998dc..22816cb97 100644
--- a/components/portal.ts
+++ b/components/portal.ts
@@ -151,7 +151,11 @@ export class Portal extends Component {
} else {
this.container = container(parentDom, anchor);
}
+ } else {
+ // let below logic to set container to default if container does not exist.
+ this.container = null;
}
+
if (!this.container) {
if (this.$senior instanceof BaseDialog) {
// Dialog and Drawer must be inserted into document.body