Skip to content

Commit

Permalink
* core: add more options to lazy content.
Browse files Browse the repository at this point in the history
  • Loading branch information
catouse committed Oct 31, 2024
1 parent fb6ec8b commit 7155dfe
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
29 changes: 24 additions & 5 deletions lib/core/src/react/components/lazy-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {LazyContentProps, CustomContentType} from '../types';
import {fetchData, type Ajax} from '../../ajax';
import {HtmlContent} from './html-content';
import {CustomContent} from './custom-content';
import {classes} from '../../helpers';

export type LazyContentState = {
loading?: boolean;
Expand All @@ -13,6 +14,8 @@ export type LazyContentState = {
export class LazyContent extends Component<LazyContentProps, LazyContentState> {
static defaultProps: Partial<LazyContentProps> = {
type: 'html',
loadingIndicator: true,
loadingClass: 'loading',
};

state: LazyContentState = {};
Expand All @@ -27,7 +30,7 @@ export class LazyContent extends Component<LazyContentProps, LazyContentState> {
const content = await fetchData(fetcher, fetcherArgs, {throws: true, dataType: type === 'custom' ? 'json' : 'text'}, fetcherThis, (ajax) => {
this._ajax = ajax;
});
this.setState({content, loading: false});
this.setState({content: content as CustomContentType, loading: false});
} catch (error) {
this.setState({error: error as Error, loading: false});
}
Expand All @@ -38,25 +41,41 @@ export class LazyContent extends Component<LazyContentProps, LazyContentState> {
this.load();
}

componentDidUpdate(previousProps: Readonly<LazyContentProps>): void {
if (this.props.fetcher !== previousProps.fetcher || this.props.fetcherArgs !== previousProps.fetcherArgs || this.props.fetcherThis !== previousProps.fetcherThis) {
this.load();
}
}

componentWillUnmount(): void {
this._ajax?.abort();
}

render(props: LazyContentProps) {
protected _renderContent(props: LazyContentProps) {
const {loading, error, content = ''} = this.state;
const {loadingText, errorText, type, ...others} = props;
const {loadingContent, errorText, type} = props;
if (loading) {
return loadingText;
return loadingContent;
}
if (error) {
return errorText ?? error.message;
}
if (type === 'html') {
return <HtmlContent html={content as string} {...others} />;
return <HtmlContent html={content as string} />;
}
if (type === 'text') {
return content;
}
return <CustomContent content={content} />;
}

render(props: LazyContentProps) {
const {loading} = this.state;
const {loadingClass, loadingIndicator, className, style, attrs, loadingText} = props;
return (
<div className={classes('lazy-content', className, loading ? loadingClass : '', loadingIndicator ? 'load-indicator' : '')} data-loading={loadingText} style={style} {...attrs}>
{this._renderContent(props)}
</div>
);
}
}
8 changes: 8 additions & 0 deletions lib/core/src/react/types/lazy-content-props.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import type {JSX} from 'preact/jsx-runtime';
import type {FetcherSetting} from '../../ajax';
import type {ClassNameLike} from '../../helpers';
import type {CustomContentType} from './custom-content-type';

export type LazyContentProps<T = string | CustomContentType, A extends unknown[] = unknown[], THIS = unknown> = {
className?: ClassNameLike;
style?: JSX.CSSProperties;
attrs?: Record<string, unknown>;
loadingClass?: ClassNameLike;
loadingIndicator?: boolean;
loadingContent?: CustomContentType;
fetcher: FetcherSetting<T, A, THIS>;
fetcherArgs: A;
fetcherThis?: THIS;
Expand Down

0 comments on commit 7155dfe

Please sign in to comment.