Skip to content

Commit

Permalink
* modal: show loading indicator on loading iframe modal.
Browse files Browse the repository at this point in the history
  • Loading branch information
catouse committed Aug 30, 2024
1 parent d9990bb commit 031477d
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 7 deletions.
28 changes: 22 additions & 6 deletions lib/modal/src/component/modal-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import {classes, CustomContent} from '@zui/core';
import {classes, CustomContent, $} from '@zui/core';
import {Toolbar} from '@zui/toolbar/src/component/toolbar';
import {Component, isValidElement} from 'preact';
import {ModalDialogOptions} from '../types';
import {Component, createRef, isValidElement} from 'preact';
import {ModalDialogOptions, ModalDialogState} from '../types';

export class ModalDialog extends Component<ModalDialogOptions> {
export class ModalDialog extends Component<ModalDialogOptions, ModalDialogState> {
static defaultProps = {closeBtn: true};

protected _ref = createRef<HTMLDivElement>();

constructor(props: ModalDialogOptions) {
super(props);
this.state = {showed: !props.waitShowEvent};
}

componentDidMount() {
this.props.afterRender?.call(this, {firstRender: true});
const {waitShowEvent, afterRender} = this.props;
afterRender?.call(this, {firstRender: true});
if (waitShowEvent) {
$(this._ref.current).on(waitShowEvent, () => {
this.setState({showed: true});
});
}
}

componentDidUpdate(): void {
Expand Down Expand Up @@ -103,17 +116,20 @@ export class ModalDialog extends Component<ModalDialogOptions> {
style,
contentClass,
children,
waitShowEvent,
} = this.props;

const loading = waitShowEvent && !this.state.showed;
return (
<div className={classes('modal-dialog', className)} style={style}>
<div ref={waitShowEvent ? this._ref : undefined} className={classes('modal-dialog', className, loading ? 'loading' : '')} style={style}>
<div className={classes('modal-content', contentClass)}>
{this.renderHeader()}
{this.renderActions()}
{this.renderBody()}
{children}
{this.renderFooter()}
</div>
{loading ? <div class="load-indicator loading" /> : null}
</div>
);
}
Expand Down
6 changes: 5 additions & 1 deletion lib/modal/src/component/modal-iframe-content.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {$} from '@zui/core';
import {Component, createRef} from 'preact';

export type ModalIframeContentProps = {
url: string;
watchHeight?: boolean;
iframeBodyClass?: string;
onLoad?: (this: ModalIframeContent) => void;
};

export type ModalIframeContentState = {
Expand Down Expand Up @@ -45,7 +47,7 @@ export class ModalIframeContent extends Component<ModalIframeContentProps> {
rob = new ResizeObserver(() => {
const body = iframeDoc.body;
const html = iframeDoc.documentElement;
const height = Math.ceil(Math.max(body.scrollHeight, body.offsetHeight, html.offsetHeight)) + 1;
const height = Math.ceil(Math.max(body.scrollHeight, body.offsetHeight, html.offsetHeight));
this.setState({height});
});
rob.observe(iframeDoc.body);
Expand All @@ -68,6 +70,8 @@ export class ModalIframeContent extends Component<ModalIframeContentProps> {
if (iframeBodyClass) {
iframeDoc.body.classList.add(iframeBodyClass);
}

$(this._ref.current).trigger('modal-iframe-loaded');
};

render() {
Expand Down
7 changes: 7 additions & 0 deletions lib/modal/src/style/modal-dialog.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,10 @@
.loading > .modal-dialog > .modal-content {
@apply -opacity-0 -invisible;
}

.modal-dialog.loading {
@apply -bg-transparent;
}
.modal-dialog.loading > .modal-content {
@apply -hidden;
}
1 change: 1 addition & 0 deletions lib/modal/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from './modal-base-options';
export * from './modal-events';
export * from './modal-trigger-options';
export * from './modal-dialog-options';
export * from './modal-dialog-state';
export * from './modal-options';
1 change: 1 addition & 0 deletions lib/modal/src/types/modal-dialog-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type ModalDialogOptions = {
footer?: CustomContentType;
footerClass?: ClassNameLike;
footerActions?: ToolbarOptions;
waitShowEvent?: string;
afterRender?: (info: {firstRender: boolean}) => void;
beforeDestroy?: () => void;
};
3 changes: 3 additions & 0 deletions lib/modal/src/types/modal-dialog-state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type ModalDialogState = {
showed?: boolean;
};
1 change: 1 addition & 0 deletions lib/modal/src/vanilla/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ async function buildIframeModal(this: Modal, _element: HTMLElement, options: Mod
return {
title,
...custom,
waitShowEvent: 'modal-iframe-loaded',
body: <ModalIframeContent url={url} watchHeight={!hasHeight} />,
};
}
Expand Down

0 comments on commit 031477d

Please sign in to comment.