@cloudtower/eagle 0.34.17 → 0.34.18
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.
- package/dist/cjs/core/Tab/Tab.js +113 -0
- package/dist/cjs/core/Tab/Tab.style.js +17 -0
- package/dist/cjs/core/Tab/Tab.type.js +9 -0
- package/dist/cjs/core/Tab/useTabAdaptiveLayout.js +73 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/stats1.html +1 -1
- package/dist/components.css +3813 -3644
- package/dist/esm/core/Tab/Tab.js +107 -0
- package/dist/esm/core/Tab/Tab.style.js +12 -0
- package/dist/esm/core/Tab/Tab.type.js +7 -0
- package/dist/esm/core/Tab/useTabAdaptiveLayout.js +71 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/stats1.html +1 -1
- package/dist/linaria.merged.scss +4649 -4439
- package/dist/src/core/Tab/Tab.d.ts +3 -0
- package/dist/src/core/Tab/Tab.style.d.ts +5 -0
- package/dist/src/core/Tab/Tab.type.d.ts +42 -0
- package/dist/src/core/Tab/index.d.ts +1 -0
- package/dist/src/core/Tab/useTabAdaptiveLayout.d.ts +23 -0
- package/dist/src/core/index.d.ts +1 -0
- package/dist/stories/docs/core/Tab.stories.d.ts +65 -0
- package/dist/style.css +3811 -3642
- package/dist/variables.scss +3 -0
- package/package.json +4 -4
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { MoreMenu16BlueIcon, MoreMenu16GrayIcon } from '@cloudtower/icons-react';
|
|
2
|
+
import { cx } from '@linaria/core';
|
|
3
|
+
import { Dropdown, Menu } from 'antd';
|
|
4
|
+
import React__default, { useRef, useState, useMemo, useLayoutEffect } from 'react';
|
|
5
|
+
import Icon from '../Icon/index.js';
|
|
6
|
+
import { Typo } from '../Typo/index.js';
|
|
7
|
+
import { TabMenuWrapper, MoreThanTooltipStyle, TabTitleElStyle, IconStyle } from './Tab.style.js';
|
|
8
|
+
import { ActiveTabType } from './Tab.type.js';
|
|
9
|
+
import { useTabAdaptiveLayout } from './useTabAdaptiveLayout.js';
|
|
10
|
+
|
|
11
|
+
const getSelectedStyle = (key, type, selectedKey, activeTabType) => {
|
|
12
|
+
return key === selectedKey && activeTabType === type ? ["__selected", Typo.Label.l1_bold_title] : [Typo.Label.l1_regular];
|
|
13
|
+
};
|
|
14
|
+
const Tab = props => {
|
|
15
|
+
const {
|
|
16
|
+
className,
|
|
17
|
+
contentClassName,
|
|
18
|
+
tabs,
|
|
19
|
+
onChange,
|
|
20
|
+
selectedKey,
|
|
21
|
+
extraSlot,
|
|
22
|
+
size = "medium"
|
|
23
|
+
} = props;
|
|
24
|
+
const tabsRef = useRef(null);
|
|
25
|
+
const extraSlotRef = useRef(null);
|
|
26
|
+
const [isClickedMoreTabItem, setIsClickedMoreTabItem] = useState(false);
|
|
27
|
+
const allTabs = useMemo(() => {
|
|
28
|
+
return tabs.reduce((map, tab) => {
|
|
29
|
+
map.set(tab.key, tab);
|
|
30
|
+
return map;
|
|
31
|
+
}, /* @__PURE__ */new Map([]));
|
|
32
|
+
}, [tabs]);
|
|
33
|
+
const selectedTab = useMemo(() => allTabs.get(selectedKey), [allTabs, selectedKey]);
|
|
34
|
+
const moreTabs = useTabAdaptiveLayout(tabs, tabsRef, extraSlotRef, selectedKey);
|
|
35
|
+
const activeTabType = useMemo(() => {
|
|
36
|
+
if (moreTabs == null ? void 0 : moreTabs.find(tab => tab.key === (selectedTab == null ? void 0 : selectedTab.key))) {
|
|
37
|
+
return ActiveTabType.More;
|
|
38
|
+
}
|
|
39
|
+
if ((selectedTab == null ? void 0 : selectedTab.key) && allTabs.get(selectedTab.key)) {
|
|
40
|
+
return ActiveTabType.Common;
|
|
41
|
+
}
|
|
42
|
+
}, [moreTabs, allTabs, selectedTab == null ? void 0 : selectedTab.key]);
|
|
43
|
+
useLayoutEffect(() => {
|
|
44
|
+
var _a;
|
|
45
|
+
if (!allTabs.get(selectedKey) && ((_a = tabs == null ? void 0 : tabs[0]) == null ? void 0 : _a.key)) {
|
|
46
|
+
onChange == null ? void 0 : onChange(tabs[0].key);
|
|
47
|
+
}
|
|
48
|
+
}, [allTabs, onChange, selectedKey, tabs]);
|
|
49
|
+
return /* @__PURE__ */React__default.createElement(TabMenuWrapper, {
|
|
50
|
+
className: cx(className, size)
|
|
51
|
+
}, /* @__PURE__ */React__default.createElement("div", {
|
|
52
|
+
className: "tab-bar"
|
|
53
|
+
}, /* @__PURE__ */React__default.createElement("div", {
|
|
54
|
+
ref: tabsRef,
|
|
55
|
+
className: "common-tab-bar"
|
|
56
|
+
}, /* tab items */
|
|
57
|
+
tabs.map(tab => /* @__PURE__ */React__default.createElement("span", {
|
|
58
|
+
className: cx("tab-item-title", "common", ...getSelectedStyle(tab.key, ActiveTabType.Common, selectedKey, activeTabType)),
|
|
59
|
+
key: tab.key,
|
|
60
|
+
onClick: () => onChange == null ? void 0 : onChange(tab.key)
|
|
61
|
+
}, typeof tab.title === "function" ? tab.title({
|
|
62
|
+
isActive: tab.key === selectedKey
|
|
63
|
+
}) : tab.title)), /* more tab items */
|
|
64
|
+
moreTabs.length > 0 && /* @__PURE__ */React__default.createElement(React__default.Fragment, null, /* @__PURE__ */React__default.createElement(Dropdown, {
|
|
65
|
+
trigger: ["click"],
|
|
66
|
+
overlayClassName: MoreThanTooltipStyle,
|
|
67
|
+
onVisibleChange: visible => setIsClickedMoreTabItem(visible),
|
|
68
|
+
getPopupContainer: triggerNode => document.querySelector(".tab-bar") || triggerNode,
|
|
69
|
+
overlay: /* @__PURE__ */React__default.createElement(Menu, {
|
|
70
|
+
className: "menu-wrapper",
|
|
71
|
+
onClick: params => {
|
|
72
|
+
setIsClickedMoreTabItem(false);
|
|
73
|
+
onChange == null ? void 0 : onChange(params.key);
|
|
74
|
+
}
|
|
75
|
+
}, moreTabs.map(tab => {
|
|
76
|
+
return /* @__PURE__ */React__default.createElement(Menu.Item, {
|
|
77
|
+
className: cx("tab-menu-item", ...getSelectedStyle(tab.key, ActiveTabType.More, selectedKey, activeTabType)),
|
|
78
|
+
key: tab.key
|
|
79
|
+
}, typeof tab.title === "function" ? tab.title({
|
|
80
|
+
isActive: tab.key === selectedKey
|
|
81
|
+
}) : tab.title);
|
|
82
|
+
}))
|
|
83
|
+
}, /* @__PURE__ */React__default.createElement("span", {
|
|
84
|
+
className: cx("tab-item-title", "more", TabTitleElStyle, activeTabType === ActiveTabType.More && "__selected", activeTabType === ActiveTabType.More ? Typo.Label.l1_bold_title : Typo.Label.l1_regular)
|
|
85
|
+
}, /* @__PURE__ */React__default.createElement(Icon, {
|
|
86
|
+
className: IconStyle,
|
|
87
|
+
hoverSrc: MoreMenu16BlueIcon,
|
|
88
|
+
src: MoreMenu16GrayIcon,
|
|
89
|
+
active: isClickedMoreTabItem
|
|
90
|
+
}), activeTabType === ActiveTabType.More && /* @__PURE__ */React__default.createElement("span", {
|
|
91
|
+
className: "tab-title-text"
|
|
92
|
+
}, typeof (selectedTab == null ? void 0 : selectedTab.title) === "function" ? selectedTab == null ? void 0 : selectedTab.title({
|
|
93
|
+
isActive: true
|
|
94
|
+
}) : selectedTab == null ? void 0 : selectedTab.title))), extraSlot && /* @__PURE__ */React__default.createElement("span", {
|
|
95
|
+
className: "E_ckaaqep"
|
|
96
|
+
}))), extraSlot && /* @__PURE__ */React__default.createElement("div", {
|
|
97
|
+
ref: extraSlotRef
|
|
98
|
+
}, extraSlot)), tabs.map(tab => /* @__PURE__ */React__default.createElement("div", {
|
|
99
|
+
style: {
|
|
100
|
+
display: tab.key === selectedKey ? "block" : "none"
|
|
101
|
+
},
|
|
102
|
+
key: tab.key,
|
|
103
|
+
className: contentClassName
|
|
104
|
+
}, tab == null ? void 0 : tab.children)));
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export { Tab };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { styled } from '@linaria/react';
|
|
2
|
+
|
|
3
|
+
const TabMenuWrapper = /*#__PURE__*/styled('div')({
|
|
4
|
+
name: "TabMenuWrapper",
|
|
5
|
+
class: "E_t1tbywr9",
|
|
6
|
+
propsAsIs: false
|
|
7
|
+
});
|
|
8
|
+
const TabTitleElStyle = "E_ti12z2";
|
|
9
|
+
const MoreThanTooltipStyle = "E_m19lu3v";
|
|
10
|
+
const IconStyle = "E_i1bmwe2m";
|
|
11
|
+
|
|
12
|
+
export { IconStyle, MoreThanTooltipStyle, TabMenuWrapper, TabTitleElStyle };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { isEqual } from 'lodash';
|
|
2
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
const getPlacementWidth = (el) => {
|
|
5
|
+
if (!el) {
|
|
6
|
+
return 0;
|
|
7
|
+
}
|
|
8
|
+
const computedStyle = window.getComputedStyle(el);
|
|
9
|
+
const width = el.offsetWidth;
|
|
10
|
+
const marginLeft = parseInt(computedStyle.marginLeft || "0");
|
|
11
|
+
const marginRight = parseInt(computedStyle.marginRight || "0");
|
|
12
|
+
return width + marginLeft + marginRight;
|
|
13
|
+
};
|
|
14
|
+
const useTabAdaptiveLayout = (tabs, tabsRef, extraSlotRef, selectedKey) => {
|
|
15
|
+
const [moreTabs, setMoreTabs] = useState([]);
|
|
16
|
+
const doAdapt = useCallback(() => {
|
|
17
|
+
if (!tabsRef.current)
|
|
18
|
+
return;
|
|
19
|
+
const tabBarEl = tabsRef.current;
|
|
20
|
+
const tabNodeList = tabBarEl.querySelectorAll(".tab-item-title.common");
|
|
21
|
+
const moreTabNode = tabBarEl.querySelector(
|
|
22
|
+
".tab-item-title.more"
|
|
23
|
+
);
|
|
24
|
+
const moreTabPlacementWidth = getPlacementWidth(moreTabNode);
|
|
25
|
+
tabNodeList.forEach((tab) => tab.classList.remove("__hidden"));
|
|
26
|
+
const maxContentWidth = getPlacementWidth(tabBarEl.parentElement) - getPlacementWidth(extraSlotRef.current) - moreTabPlacementWidth;
|
|
27
|
+
let tabsTotalWidth = 24;
|
|
28
|
+
const hiddenItems = [];
|
|
29
|
+
let endIndex = Infinity;
|
|
30
|
+
for (let i = 0; i < tabNodeList.length; i++) {
|
|
31
|
+
const tab = tabNodeList[i];
|
|
32
|
+
const tabWidth = getPlacementWidth(tab);
|
|
33
|
+
if (maxContentWidth >= tabsTotalWidth + tabWidth) {
|
|
34
|
+
tabsTotalWidth += tabWidth;
|
|
35
|
+
} else {
|
|
36
|
+
endIndex = i;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
while (endIndex <= tabNodeList.length - 1) {
|
|
41
|
+
tabNodeList[endIndex].classList.add("__hidden");
|
|
42
|
+
hiddenItems.push(tabs[endIndex]);
|
|
43
|
+
endIndex++;
|
|
44
|
+
}
|
|
45
|
+
setMoreTabs((prevMoreTabs) => {
|
|
46
|
+
if (!isEqual(hiddenItems, prevMoreTabs)) {
|
|
47
|
+
return hiddenItems;
|
|
48
|
+
}
|
|
49
|
+
return prevMoreTabs;
|
|
50
|
+
});
|
|
51
|
+
}, [tabs, tabsRef, extraSlotRef]);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
doAdapt();
|
|
54
|
+
}, [doAdapt, selectedKey]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
var _a;
|
|
57
|
+
const parentElement = (_a = tabsRef.current) == null ? void 0 : _a.parentElement;
|
|
58
|
+
if (!parentElement)
|
|
59
|
+
return;
|
|
60
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
61
|
+
doAdapt();
|
|
62
|
+
});
|
|
63
|
+
resizeObserver.observe(parentElement);
|
|
64
|
+
return () => {
|
|
65
|
+
resizeObserver.disconnect();
|
|
66
|
+
};
|
|
67
|
+
}, [doAdapt, tabsRef]);
|
|
68
|
+
return moreTabs;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export { useTabAdaptiveLayout };
|
package/dist/esm/index.js
CHANGED
|
@@ -117,6 +117,7 @@ export { SmallDialog } from './core/SmallDialog/SmallDialog.js';
|
|
|
117
117
|
export { CloseIconStyle, DialogStyle, ErrorTextStyle, FooterStyle, ModelContentSkeletonStyle, ModelInitializingErrorStyle, ModelTitleSkeletonStyle } from './core/SmallDialog/SmallDialog.style.js';
|
|
118
118
|
export { CircleProgress } from './core/StepProgress/index.js';
|
|
119
119
|
export { CannotOperationInfo, CommonContent, ContentWrapper, Desc, Description, Divider, Dot, ErrorSpan, ExpandArrow, FieldTitle, FormField, FormItemDiv, FormSectionTitle, FormWrapper, FullView, HorizontalWizardModalCompactStyle, HorizontalWizardModalLooseStyle, InfoAlert, InputStyle, KitInputStyle, LeftEndInputStyle, LeftEndSelectStyle, LightDesc, LoadingWrapper, ModalBody, ModalWrapper, NameTag, NormalAlert, NoticeAlert, OperationWraper, RadioDesc, RightEndInputStyle, RightEndSelectStyle, SelectOptionDisabledText, TagSpan, TertiaryText, UnitStyle, WarningAlert, WizardBody, radioStyle } from './core/Styled/index.js';
|
|
120
|
+
export { Tab } from './core/Tab/Tab.js';
|
|
120
121
|
export { useTableBodyHasScrollBar } from './core/Table/common.js';
|
|
121
122
|
export { TableSkeleton } from './core/Table/TableSkeleton.js';
|
|
122
123
|
export { ColumnTitle, EmptyRowMenu, KitTableContext, TableLoading } from './core/Table/TableWidget.js';
|