@ioca/react 1.5.23 → 1.5.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
const AsyncContent = (props) => {
|
|
5
|
+
const { load, loader } = props;
|
|
6
|
+
const [state, setState] = useState({ status: "loading" });
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
let cancelled = false;
|
|
9
|
+
setState({ status: "loading" });
|
|
10
|
+
load()
|
|
11
|
+
.then((module) => {
|
|
12
|
+
if (!cancelled) {
|
|
13
|
+
setState({ status: "loaded", Component: module.default });
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
.catch((error) => {
|
|
17
|
+
if (!cancelled) {
|
|
18
|
+
setState({ status: "error", error });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return () => {
|
|
22
|
+
cancelled = true;
|
|
23
|
+
};
|
|
24
|
+
}, [load]);
|
|
25
|
+
switch (state.status) {
|
|
26
|
+
case "loaded":
|
|
27
|
+
return jsx(state.Component, {});
|
|
28
|
+
case "error":
|
|
29
|
+
return null;
|
|
30
|
+
case "loading":
|
|
31
|
+
default:
|
|
32
|
+
return loader ?? null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export { AsyncContent as default };
|
|
@@ -21,11 +21,17 @@ const isSameTabs = (prev, next) => prev.length === next.length &&
|
|
|
21
21
|
const getParsedTabs = (items, children) => {
|
|
22
22
|
const contents = new Map();
|
|
23
23
|
if (!items) {
|
|
24
|
+
const lazyLoaders = new Map();
|
|
24
25
|
const tabs = Children.map(children, (node, i) => {
|
|
25
26
|
const { key, props: nodeProps } = node;
|
|
26
27
|
const { title, children: tabChildren, content, keepDOM, closable, } = nodeProps;
|
|
27
28
|
const tabKey = String(key ?? i);
|
|
28
|
-
|
|
29
|
+
if (typeof content === "function") {
|
|
30
|
+
lazyLoaders.set(tabKey, { load: content });
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
contents.set(tabKey, tabChildren ?? content);
|
|
34
|
+
}
|
|
29
35
|
return {
|
|
30
36
|
key: tabKey,
|
|
31
37
|
title,
|
|
@@ -36,16 +42,23 @@ const getParsedTabs = (items, children) => {
|
|
|
36
42
|
return {
|
|
37
43
|
tabs,
|
|
38
44
|
contents,
|
|
45
|
+
lazyLoaders,
|
|
39
46
|
keys: new Set(tabs.map((tab) => String(tab.key))),
|
|
40
47
|
};
|
|
41
48
|
}
|
|
49
|
+
const lazyLoaders = new Map();
|
|
42
50
|
const tabs = items.map((item, i) => {
|
|
43
51
|
if (["string", "number"].includes(typeof item)) {
|
|
44
52
|
const key = String(item);
|
|
45
53
|
return { key, title: item };
|
|
46
54
|
}
|
|
47
55
|
const key = String(item.key ?? i);
|
|
48
|
-
|
|
56
|
+
if (typeof item.content === "function") {
|
|
57
|
+
lazyLoaders.set(key, { load: item.content });
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
contents.set(key, item.content);
|
|
61
|
+
}
|
|
49
62
|
const { content, ...rest } = item;
|
|
50
63
|
return {
|
|
51
64
|
...rest,
|
|
@@ -55,6 +68,7 @@ const getParsedTabs = (items, children) => {
|
|
|
55
68
|
return {
|
|
56
69
|
tabs,
|
|
57
70
|
contents,
|
|
71
|
+
lazyLoaders,
|
|
58
72
|
keys: new Set(tabs.map((tab) => String(tab.key))),
|
|
59
73
|
};
|
|
60
74
|
};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import { useRef, useState, useMemo, useEffect, useImperativeHandle } from 'react';
|
|
4
4
|
import { useIntersectionObserver, useSize } from '../../js/hooks.js';
|
|
5
|
+
import AsyncContent from './async-content.js';
|
|
5
6
|
import TabsContents from './contents.js';
|
|
6
7
|
import { defaultRenderMore, getParsedTabs, isSameTabs, emptyBarStyle } from './helper.js';
|
|
7
8
|
import Item from './item.js';
|
|
8
9
|
import TabsNavs from './navs.js';
|
|
9
10
|
|
|
10
11
|
const Tabs = ((props) => {
|
|
11
|
-
const { ref, active, tabs: items, type = "default", prepend, append, children, className, vertical, toggable, navsJustify = "start", navsClass, bar = true, hideMore, barClass, renderMore = defaultRenderMore, onTabChange, ...rest } = props;
|
|
12
|
+
const { ref, active, tabs: items, type = "default", prepend, append, children, className, vertical, toggable, loader, navsJustify = "start", navsClass, bar = true, hideMore, barClass, renderMore = defaultRenderMore, onTabChange, ...rest } = props;
|
|
12
13
|
const navRefs = useRef([]);
|
|
13
14
|
const navsRef = useRef(null);
|
|
14
15
|
const contentsRef = useRef(new Map());
|
|
@@ -34,6 +35,9 @@ const Tabs = ((props) => {
|
|
|
34
35
|
const nextContents = new Map(parsedTabs.contents);
|
|
35
36
|
const sourceTabs = parsedTabs.tabs;
|
|
36
37
|
const sourceKeys = parsedTabs.keys;
|
|
38
|
+
parsedTabs.lazyLoaders.forEach((lazyLoader, key) => {
|
|
39
|
+
nextContents.set(key, jsx(AsyncContent, { load: lazyLoader.load, loader: loader }));
|
|
40
|
+
});
|
|
37
41
|
hiddenSourceKeysRef.current.forEach((key) => {
|
|
38
42
|
if (!sourceKeys.has(key)) {
|
|
39
43
|
hiddenSourceKeysRef.current.delete(key);
|
|
@@ -60,7 +64,12 @@ const Tabs = ((props) => {
|
|
|
60
64
|
open(currentTabs[i].key ?? `${i}`);
|
|
61
65
|
return;
|
|
62
66
|
}
|
|
63
|
-
|
|
67
|
+
if (typeof tab.content === "function") {
|
|
68
|
+
contentsRef.current.set(tkey, jsx(AsyncContent, { load: tab.content, loader: loader }));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
contentsRef.current.set(tkey, tab.content);
|
|
72
|
+
}
|
|
64
73
|
const { content, ...rest } = tab;
|
|
65
74
|
setTabs((ts) => {
|
|
66
75
|
const nextTabs = [...ts];
|
package/lib/index.js
CHANGED
|
@@ -5942,6 +5942,38 @@ const Swiper = ((props) => {
|
|
|
5942
5942
|
});
|
|
5943
5943
|
Swiper.Item = Item$1;
|
|
5944
5944
|
|
|
5945
|
+
const AsyncContent = (props) => {
|
|
5946
|
+
const { load, loader } = props;
|
|
5947
|
+
const [state, setState] = useState({ status: "loading" });
|
|
5948
|
+
useEffect(() => {
|
|
5949
|
+
let cancelled = false;
|
|
5950
|
+
setState({ status: "loading" });
|
|
5951
|
+
load()
|
|
5952
|
+
.then((module) => {
|
|
5953
|
+
if (!cancelled) {
|
|
5954
|
+
setState({ status: "loaded", Component: module.default });
|
|
5955
|
+
}
|
|
5956
|
+
})
|
|
5957
|
+
.catch((error) => {
|
|
5958
|
+
if (!cancelled) {
|
|
5959
|
+
setState({ status: "error", error });
|
|
5960
|
+
}
|
|
5961
|
+
});
|
|
5962
|
+
return () => {
|
|
5963
|
+
cancelled = true;
|
|
5964
|
+
};
|
|
5965
|
+
}, [load]);
|
|
5966
|
+
switch (state.status) {
|
|
5967
|
+
case "loaded":
|
|
5968
|
+
return jsx(state.Component, {});
|
|
5969
|
+
case "error":
|
|
5970
|
+
return null;
|
|
5971
|
+
case "loading":
|
|
5972
|
+
default:
|
|
5973
|
+
return loader ?? null;
|
|
5974
|
+
}
|
|
5975
|
+
};
|
|
5976
|
+
|
|
5945
5977
|
const TabsContents = (props) => {
|
|
5946
5978
|
const { tabs, activeKey, cachedTabKeySet, getContent } = props;
|
|
5947
5979
|
return (jsx("div", { className: "i-tab-contents", children: tabs.map((tab, i) => {
|
|
@@ -5973,11 +6005,17 @@ const isSameTabs = (prev, next) => prev.length === next.length &&
|
|
|
5973
6005
|
const getParsedTabs = (items, children) => {
|
|
5974
6006
|
const contents = new Map();
|
|
5975
6007
|
if (!items) {
|
|
6008
|
+
const lazyLoaders = new Map();
|
|
5976
6009
|
const tabs = Children.map(children, (node, i) => {
|
|
5977
6010
|
const { key, props: nodeProps } = node;
|
|
5978
6011
|
const { title, children: tabChildren, content, keepDOM, closable, } = nodeProps;
|
|
5979
6012
|
const tabKey = String(key ?? i);
|
|
5980
|
-
|
|
6013
|
+
if (typeof content === "function") {
|
|
6014
|
+
lazyLoaders.set(tabKey, { load: content });
|
|
6015
|
+
}
|
|
6016
|
+
else {
|
|
6017
|
+
contents.set(tabKey, tabChildren ?? content);
|
|
6018
|
+
}
|
|
5981
6019
|
return {
|
|
5982
6020
|
key: tabKey,
|
|
5983
6021
|
title,
|
|
@@ -5988,16 +6026,23 @@ const getParsedTabs = (items, children) => {
|
|
|
5988
6026
|
return {
|
|
5989
6027
|
tabs,
|
|
5990
6028
|
contents,
|
|
6029
|
+
lazyLoaders,
|
|
5991
6030
|
keys: new Set(tabs.map((tab) => String(tab.key))),
|
|
5992
6031
|
};
|
|
5993
6032
|
}
|
|
6033
|
+
const lazyLoaders = new Map();
|
|
5994
6034
|
const tabs = items.map((item, i) => {
|
|
5995
6035
|
if (["string", "number"].includes(typeof item)) {
|
|
5996
6036
|
const key = String(item);
|
|
5997
6037
|
return { key, title: item };
|
|
5998
6038
|
}
|
|
5999
6039
|
const key = String(item.key ?? i);
|
|
6000
|
-
|
|
6040
|
+
if (typeof item.content === "function") {
|
|
6041
|
+
lazyLoaders.set(key, { load: item.content });
|
|
6042
|
+
}
|
|
6043
|
+
else {
|
|
6044
|
+
contents.set(key, item.content);
|
|
6045
|
+
}
|
|
6001
6046
|
const { content, ...rest } = item;
|
|
6002
6047
|
return {
|
|
6003
6048
|
...rest,
|
|
@@ -6007,6 +6052,7 @@ const getParsedTabs = (items, children) => {
|
|
|
6007
6052
|
return {
|
|
6008
6053
|
tabs,
|
|
6009
6054
|
contents,
|
|
6055
|
+
lazyLoaders,
|
|
6010
6056
|
keys: new Set(tabs.map((tab) => String(tab.key))),
|
|
6011
6057
|
};
|
|
6012
6058
|
};
|
|
@@ -6038,7 +6084,7 @@ const TabsNavs = (props) => {
|
|
|
6038
6084
|
var TabsNavs$1 = memo(TabsNavs);
|
|
6039
6085
|
|
|
6040
6086
|
const Tabs = ((props) => {
|
|
6041
|
-
const { ref, active, tabs: items, type = "default", prepend, append, children, className, vertical, toggable, navsJustify = "start", navsClass, bar = true, hideMore, barClass, renderMore = defaultRenderMore, onTabChange, ...rest } = props;
|
|
6087
|
+
const { ref, active, tabs: items, type = "default", prepend, append, children, className, vertical, toggable, loader, navsJustify = "start", navsClass, bar = true, hideMore, barClass, renderMore = defaultRenderMore, onTabChange, ...rest } = props;
|
|
6042
6088
|
const navRefs = useRef([]);
|
|
6043
6089
|
const navsRef = useRef(null);
|
|
6044
6090
|
const contentsRef = useRef(new Map());
|
|
@@ -6064,6 +6110,9 @@ const Tabs = ((props) => {
|
|
|
6064
6110
|
const nextContents = new Map(parsedTabs.contents);
|
|
6065
6111
|
const sourceTabs = parsedTabs.tabs;
|
|
6066
6112
|
const sourceKeys = parsedTabs.keys;
|
|
6113
|
+
parsedTabs.lazyLoaders.forEach((lazyLoader, key) => {
|
|
6114
|
+
nextContents.set(key, jsx(AsyncContent, { load: lazyLoader.load, loader: loader }));
|
|
6115
|
+
});
|
|
6067
6116
|
hiddenSourceKeysRef.current.forEach((key) => {
|
|
6068
6117
|
if (!sourceKeys.has(key)) {
|
|
6069
6118
|
hiddenSourceKeysRef.current.delete(key);
|
|
@@ -6090,7 +6139,12 @@ const Tabs = ((props) => {
|
|
|
6090
6139
|
open(currentTabs[i].key ?? `${i}`);
|
|
6091
6140
|
return;
|
|
6092
6141
|
}
|
|
6093
|
-
|
|
6142
|
+
if (typeof tab.content === "function") {
|
|
6143
|
+
contentsRef.current.set(tkey, jsx(AsyncContent, { load: tab.content, loader: loader }));
|
|
6144
|
+
}
|
|
6145
|
+
else {
|
|
6146
|
+
contentsRef.current.set(tkey, tab.content);
|
|
6147
|
+
}
|
|
6094
6148
|
const { content, ...rest } = tab;
|
|
6095
6149
|
setTabs((ts) => {
|
|
6096
6150
|
const nextTabs = [...ts];
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { ForwardRefExoticComponent, Ref, ReactNode, RefObject, CSSProperties } from 'react';
|
|
1
|
+
import { ForwardRefExoticComponent, Ref, ReactNode, ComponentType, RefObject, CSSProperties } from 'react';
|
|
2
2
|
import Item from './item.js';
|
|
3
3
|
|
|
4
4
|
interface ITabItem {
|
|
5
5
|
key?: string;
|
|
6
6
|
title?: ReactNode;
|
|
7
|
-
content?: ReactNode
|
|
7
|
+
content?: ReactNode | (() => Promise<{
|
|
8
|
+
default: ComponentType<any>;
|
|
9
|
+
}>);
|
|
8
10
|
closable?: boolean;
|
|
9
11
|
keepDOM?: boolean;
|
|
10
12
|
intersecting?: boolean;
|
|
@@ -28,6 +30,7 @@ interface ITabs {
|
|
|
28
30
|
children?: ReactNode;
|
|
29
31
|
style?: CSSProperties;
|
|
30
32
|
renderMore?: (moreTabs: ITabItem[]) => ReactNode;
|
|
33
|
+
loader?: ReactNode;
|
|
31
34
|
onTabChange?: (to?: string, from?: string) => void;
|
|
32
35
|
}
|
|
33
36
|
interface RefTabs {
|