@ioca/react 1.5.5 → 1.5.7
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/lib/cjs/components/editor/controls.js +12 -34
- package/lib/cjs/components/editor/controls.js.map +1 -1
- package/lib/cjs/components/editor/editor.js +34 -27
- package/lib/cjs/components/editor/editor.js.map +1 -1
- package/lib/cjs/components/editor/memtion.js +93 -4
- package/lib/cjs/components/editor/memtion.js.map +1 -1
- package/lib/cjs/components/picker/colors/index.js +6 -5
- package/lib/cjs/components/picker/colors/index.js.map +1 -1
- package/lib/cjs/components/select/select.js +4 -4
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/tabs/contents.js +28 -0
- package/lib/cjs/components/tabs/contents.js.map +1 -0
- package/lib/cjs/components/tabs/helper.js +68 -0
- package/lib/cjs/components/tabs/helper.js.map +1 -0
- package/lib/cjs/components/tabs/navs.js +38 -0
- package/lib/cjs/components/tabs/navs.js.map +1 -0
- package/lib/cjs/components/tabs/tabs.js +62 -84
- package/lib/cjs/components/tabs/tabs.js.map +1 -1
- package/lib/css/index.css +1 -1
- package/lib/css/index.css.map +1 -1
- package/lib/css/reset.css +2 -2
- package/lib/es/components/editor/controls.js +13 -35
- package/lib/es/components/editor/controls.js.map +1 -1
- package/lib/es/components/editor/editor.js +35 -28
- package/lib/es/components/editor/editor.js.map +1 -1
- package/lib/es/components/editor/memtion.js +93 -5
- package/lib/es/components/editor/memtion.js.map +1 -1
- package/lib/es/components/picker/colors/index.js +6 -5
- package/lib/es/components/picker/colors/index.js.map +1 -1
- package/lib/es/components/select/select.js +4 -4
- package/lib/es/components/select/select.js.map +1 -1
- package/lib/es/components/tabs/contents.js +20 -0
- package/lib/es/components/tabs/contents.js.map +1 -0
- package/lib/es/components/tabs/helper.js +63 -0
- package/lib/es/components/tabs/helper.js.map +1 -0
- package/lib/es/components/tabs/navs.js +30 -0
- package/lib/es/components/tabs/navs.js.map +1 -0
- package/lib/es/components/tabs/tabs.js +64 -86
- package/lib/es/components/tabs/tabs.js.map +1 -1
- package/lib/index.js +297 -154
- package/lib/types/components/editor/type.d.ts +1 -1
- package/lib/types/components/picker/type.d.ts +3 -1
- package/lib/types/components/tabs/type.d.ts +4 -4
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import { debounce, uid, throttle, title } from 'radash';
|
|
4
4
|
import { useState, useRef, useCallback, useEffect, useMemo, Children, cloneElement, createElement, isValidElement, Fragment as Fragment$1, useTransition, forwardRef, useLayoutEffect, memo, createContext, useContext, useImperativeHandle } from 'react';
|
|
5
|
-
import { SkipPreviousRound, CloseRound, MinusRound, PlusRound, InboxTwotone,
|
|
5
|
+
import { SkipPreviousRound, CloseRound, MinusRound, PlusRound, InboxTwotone, UndoRound, RedoRound, FormatBoldRound, FormatItalicRound, FormatUnderlinedRound, StrikethroughSRound, ClearAllRound, PlayArrowRound, PauseRound, StopRound, VolumeDownRound, VolumeOffRound, FullscreenRound, FullscreenExitRound, FeedOutlined, AspectRatioRound, OpenInNewRound, FileDownloadOutlined, RotateRightRound, RotateLeftRound, KeyboardArrowLeftRound, KeyboardArrowRightRound, KeyboardDoubleArrowUpRound, SyncAltRound, VisibilityRound, VisibilityOffRound, MoreHorizRound, SearchRound, CheckRound, UnfoldMoreRound, CalendarMonthTwotone, AccessTimeRound, InfoOutlined, KeyboardArrowDownRound, ListAltRound, DriveFolderUploadOutlined, PlusSharp } from '@ricons/material';
|
|
6
6
|
import { createRoot } from 'react-dom/client';
|
|
7
7
|
import { createPortal } from 'react-dom';
|
|
8
8
|
import xss from 'xss';
|
|
@@ -1867,57 +1867,67 @@ const xssOptions = {
|
|
|
1867
1867
|
const handleMouseDown = (e) => {
|
|
1868
1868
|
e.preventDefault();
|
|
1869
1869
|
};
|
|
1870
|
-
const
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
},
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
onClick: () => exec("italic"),
|
|
1878
|
-
},
|
|
1879
|
-
underline: {
|
|
1870
|
+
const defaultControls = [
|
|
1871
|
+
{ key: "undo", icon: jsx(UndoRound, {}), onClick: () => exec("undo") },
|
|
1872
|
+
{ key: "redo", icon: jsx(RedoRound, {}), onClick: () => exec("redo") },
|
|
1873
|
+
{ key: "bold", icon: jsx(FormatBoldRound, {}), onClick: () => exec("bold") },
|
|
1874
|
+
{ key: "italic", icon: jsx(FormatItalicRound, {}), onClick: () => exec("italic") },
|
|
1875
|
+
{
|
|
1876
|
+
key: "underline",
|
|
1880
1877
|
icon: jsx(FormatUnderlinedRound, {}),
|
|
1881
1878
|
onClick: () => exec("underline"),
|
|
1882
1879
|
},
|
|
1883
|
-
|
|
1880
|
+
{
|
|
1881
|
+
key: "strike",
|
|
1884
1882
|
icon: jsx(StrikethroughSRound, {}),
|
|
1885
1883
|
onClick: () => exec("strikeThrough"),
|
|
1886
1884
|
},
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
onClick: () => exec("redo"),
|
|
1890
|
-
},
|
|
1891
|
-
undo: {
|
|
1892
|
-
icon: jsx(UndoRound, {}),
|
|
1893
|
-
onClick: () => exec("undo"),
|
|
1894
|
-
},
|
|
1895
|
-
clear: {
|
|
1885
|
+
{
|
|
1886
|
+
key: "clear",
|
|
1896
1887
|
icon: jsx(ClearAllRound, {}),
|
|
1897
1888
|
onClick: () => exec("removeFormat"),
|
|
1898
1889
|
},
|
|
1899
|
-
};
|
|
1900
|
-
const defaultKeys = [
|
|
1901
|
-
"undo",
|
|
1902
|
-
"redo",
|
|
1903
|
-
"bold",
|
|
1904
|
-
"italic",
|
|
1905
|
-
"underline",
|
|
1906
|
-
"strike",
|
|
1907
|
-
"clear",
|
|
1908
1890
|
];
|
|
1909
|
-
const typedFnMap = fnMap;
|
|
1910
1891
|
function getControls(options) {
|
|
1911
1892
|
const { controlBtnProps, addtionControls, getSelection } = options;
|
|
1912
|
-
const controls =
|
|
1913
|
-
const { icon, onClick } = typedFnMap[k];
|
|
1914
|
-
return (jsx(Button, { ...controlBtnProps, onMouseDown: handleMouseDown, onClick: onClick, children: jsx(Icon, { icon: icon }) }, k));
|
|
1915
|
-
});
|
|
1893
|
+
const controls = defaultControls.map(({ key, icon, onClick }) => (jsx(Button, { ...controlBtnProps, onMouseDown: handleMouseDown, onClick: onClick, children: jsx(Icon, { icon: icon }) }, key)));
|
|
1916
1894
|
const extControls = (addtionControls ?? []).map((item, index) => (jsx(Button, { ...controlBtnProps, onMouseDown: handleMouseDown, onClick: (e) => item.onClick?.(getSelection(), e), children: item.icon }, `addtion-${index}`)));
|
|
1917
1895
|
return [...controls, ...extControls];
|
|
1918
1896
|
}
|
|
1919
1897
|
|
|
1920
1898
|
const MEMTION_TAG_CLASS_NAME = "i-memtion-tag";
|
|
1899
|
+
const blockTags = new Set([
|
|
1900
|
+
"ADDRESS",
|
|
1901
|
+
"ARTICLE",
|
|
1902
|
+
"ASIDE",
|
|
1903
|
+
"BLOCKQUOTE",
|
|
1904
|
+
"DIV",
|
|
1905
|
+
"DL",
|
|
1906
|
+
"FIELDSET",
|
|
1907
|
+
"FIGCAPTION",
|
|
1908
|
+
"FIGURE",
|
|
1909
|
+
"FOOTER",
|
|
1910
|
+
"FORM",
|
|
1911
|
+
"H1",
|
|
1912
|
+
"H2",
|
|
1913
|
+
"H3",
|
|
1914
|
+
"H4",
|
|
1915
|
+
"H5",
|
|
1916
|
+
"H6",
|
|
1917
|
+
"HEADER",
|
|
1918
|
+
"LI",
|
|
1919
|
+
"MAIN",
|
|
1920
|
+
"NAV",
|
|
1921
|
+
"OL",
|
|
1922
|
+
"P",
|
|
1923
|
+
"PRE",
|
|
1924
|
+
"SECTION",
|
|
1925
|
+
"TABLE",
|
|
1926
|
+
"TD",
|
|
1927
|
+
"TH",
|
|
1928
|
+
"TR",
|
|
1929
|
+
"UL",
|
|
1930
|
+
]);
|
|
1921
1931
|
const escapeHtmlAttr = (value) => value
|
|
1922
1932
|
.replaceAll("&", "&")
|
|
1923
1933
|
.replaceAll('"', """)
|
|
@@ -1968,14 +1978,11 @@ const insertMemtionOption = ({ editor, range, mode, memtion, option, sanitizeVal
|
|
|
1968
1978
|
const html = getInsertHtml(memtion, option, sanitizeValue);
|
|
1969
1979
|
const fragment = nextRange.createContextualFragment(html);
|
|
1970
1980
|
const lastNode = fragment.lastChild;
|
|
1971
|
-
const spacing = document.createTextNode(" ");
|
|
1972
1981
|
nextRange.insertNode(fragment);
|
|
1973
1982
|
if (lastNode) {
|
|
1974
1983
|
nextRange.setStartAfter(lastNode);
|
|
1975
1984
|
nextRange.collapse(true);
|
|
1976
1985
|
}
|
|
1977
|
-
nextRange.insertNode(spacing);
|
|
1978
|
-
nextRange.setStartAfter(spacing);
|
|
1979
1986
|
}
|
|
1980
1987
|
nextRange.collapse(true);
|
|
1981
1988
|
browserSelection.removeAllRanges();
|
|
@@ -2005,6 +2012,60 @@ const filterMemtionOptions = (options, keyword) => {
|
|
|
2005
2012
|
};
|
|
2006
2013
|
const isMemtionTag = (node) => node instanceof HTMLElement &&
|
|
2007
2014
|
node.classList.contains(MEMTION_TAG_CLASS_NAME);
|
|
2015
|
+
const appendBreak = (container) => {
|
|
2016
|
+
if (!container.lastChild || container.lastChild.nodeName === "BR") {
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
container.appendChild(document.createElement("br"));
|
|
2020
|
+
};
|
|
2021
|
+
const appendPlaintextOnMemtionNode = (container, node) => {
|
|
2022
|
+
if (!node)
|
|
2023
|
+
return;
|
|
2024
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
2025
|
+
container.appendChild(document.createTextNode((node.textContent ?? "").replaceAll("\r", "")));
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2028
|
+
if (!(node instanceof HTMLElement)) {
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
2031
|
+
if (isMemtionTag(node)) {
|
|
2032
|
+
const tag = document.createElement("span");
|
|
2033
|
+
const memtionValue = node.getAttribute("data-memtion-value");
|
|
2034
|
+
tag.className = MEMTION_TAG_CLASS_NAME;
|
|
2035
|
+
tag.setAttribute("contenteditable", "false");
|
|
2036
|
+
if (memtionValue !== null) {
|
|
2037
|
+
tag.setAttribute("data-memtion-value", memtionValue);
|
|
2038
|
+
}
|
|
2039
|
+
tag.innerHTML = node.innerHTML;
|
|
2040
|
+
container.appendChild(tag);
|
|
2041
|
+
return;
|
|
2042
|
+
}
|
|
2043
|
+
if (node.tagName === "BR") {
|
|
2044
|
+
appendBreak(container);
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
Array.from(node.childNodes).forEach((child) => {
|
|
2048
|
+
appendPlaintextOnMemtionNode(container, child);
|
|
2049
|
+
});
|
|
2050
|
+
if (blockTags.has(node.tagName)) {
|
|
2051
|
+
appendBreak(container);
|
|
2052
|
+
}
|
|
2053
|
+
};
|
|
2054
|
+
const sanitizePlaintextOnMemtionHtml = (value) => {
|
|
2055
|
+
if (typeof document === "undefined") {
|
|
2056
|
+
return value;
|
|
2057
|
+
}
|
|
2058
|
+
const source = document.createElement("div");
|
|
2059
|
+
const result = document.createElement("div");
|
|
2060
|
+
source.innerHTML = value;
|
|
2061
|
+
Array.from(source.childNodes).forEach((child) => {
|
|
2062
|
+
appendPlaintextOnMemtionNode(result, child);
|
|
2063
|
+
});
|
|
2064
|
+
while (result.lastChild?.nodeName === "BR") {
|
|
2065
|
+
result.lastChild.remove();
|
|
2066
|
+
}
|
|
2067
|
+
return result.innerHTML;
|
|
2068
|
+
};
|
|
2008
2069
|
const getAdjacentMemtionTag = (range, direction) => {
|
|
2009
2070
|
const { startContainer, startOffset } = range;
|
|
2010
2071
|
if (startContainer.nodeType === Node.TEXT_NODE) {
|
|
@@ -2062,11 +2123,15 @@ const Memtion = (props) => {
|
|
|
2062
2123
|
if (!visible || !rect || !options?.length) {
|
|
2063
2124
|
return null;
|
|
2064
2125
|
}
|
|
2065
|
-
|
|
2126
|
+
const content = (jsx(List$1, { className: "i-editor-memtion", type: "option", style: {
|
|
2066
2127
|
position: "fixed",
|
|
2067
2128
|
top: rect.bottom,
|
|
2068
2129
|
left: rect.left,
|
|
2069
2130
|
}, children: options.map((option, i) => (jsx(List$1.Item, { type: "option", active: i === activeIndex, onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => onActiveChange?.(i), onClick: () => onSelect?.(option), children: option.label }, `${option.value}-${i}`))) }));
|
|
2131
|
+
if (typeof document === "undefined") {
|
|
2132
|
+
return content;
|
|
2133
|
+
}
|
|
2134
|
+
return createPortal(content, document.body);
|
|
2070
2135
|
};
|
|
2071
2136
|
var Memtion$1 = memo(Memtion);
|
|
2072
2137
|
|
|
@@ -2081,18 +2146,28 @@ const Editor = (props) => {
|
|
|
2081
2146
|
const selectionRef = useRef(null);
|
|
2082
2147
|
const memtionTriggerRangeRef = useRef(null);
|
|
2083
2148
|
const pendingMemtionRef = useRef(false);
|
|
2149
|
+
const isPlaintextMode = mode === "plaintext";
|
|
2150
|
+
const isRichMode = mode === "rich";
|
|
2151
|
+
const isPlaintextOnMemtionMode = mode === "plaintextOnMemtion";
|
|
2084
2152
|
const [memtionVisible, setMemtionVisible] = useState(false);
|
|
2085
2153
|
const [memtionRect, setMemtionRect] = useState(null);
|
|
2086
2154
|
const [memtionKeyword, setMemtionKeyword] = useState("");
|
|
2087
2155
|
const [memtionActiveIndex, setMemtionActiveIndex] = useState(0);
|
|
2088
2156
|
const memtionOptions = useMemo(() => filterMemtionOptions(memtion?.options ?? [], memtionKeyword), [memtion?.options, memtionKeyword]);
|
|
2089
2157
|
const sanitizeValue = (nextValue) => {
|
|
2090
|
-
if (
|
|
2158
|
+
if (isPlaintextMode) {
|
|
2091
2159
|
return nextValue === "\n" ? "" : nextValue;
|
|
2092
2160
|
}
|
|
2093
|
-
const safeHtml =
|
|
2161
|
+
const safeHtml = isPlaintextOnMemtionMode
|
|
2162
|
+
? sanitizePlaintextOnMemtionHtml(xss(nextValue, xssOptions))
|
|
2163
|
+
: xss(nextValue, xssOptions);
|
|
2094
2164
|
return safeHtml === "<br>" ? "" : safeHtml;
|
|
2095
2165
|
};
|
|
2166
|
+
const syncHeight = () => {
|
|
2167
|
+
if (autosize && editorRef.current) {
|
|
2168
|
+
editorRef.current.style.height = `${editorRef.current.scrollHeight}px`;
|
|
2169
|
+
}
|
|
2170
|
+
};
|
|
2096
2171
|
const rememberSelection = () => {
|
|
2097
2172
|
if (!editorRef.current)
|
|
2098
2173
|
return;
|
|
@@ -2112,18 +2187,18 @@ const Editor = (props) => {
|
|
|
2112
2187
|
if (!editorRef.current)
|
|
2113
2188
|
return;
|
|
2114
2189
|
const safeValue = sanitizeValue(nextValue);
|
|
2115
|
-
if (
|
|
2190
|
+
if (isPlaintextMode) {
|
|
2116
2191
|
editorRef.current.textContent = safeValue;
|
|
2117
2192
|
return;
|
|
2118
2193
|
}
|
|
2119
2194
|
editorRef.current.innerHTML = safeValue;
|
|
2120
2195
|
};
|
|
2121
2196
|
const getEditorValue = (sanitize = false) => {
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2197
|
+
const nextValue = !editorRef.current
|
|
2198
|
+
? ""
|
|
2199
|
+
: isPlaintextMode
|
|
2200
|
+
? (editorRef.current.textContent ?? "")
|
|
2201
|
+
: editorRef.current.innerHTML;
|
|
2127
2202
|
return sanitize ? sanitizeValue(nextValue) : nextValue;
|
|
2128
2203
|
};
|
|
2129
2204
|
const hideMemtion = () => {
|
|
@@ -2155,22 +2230,18 @@ const Editor = (props) => {
|
|
|
2155
2230
|
if (e.defaultPrevented)
|
|
2156
2231
|
return;
|
|
2157
2232
|
e.preventDefault();
|
|
2158
|
-
if (mode === "plaintext") {
|
|
2159
|
-
const text = e.clipboardData.getData("text/plain");
|
|
2160
|
-
exec("insertText", false, text);
|
|
2161
|
-
return;
|
|
2162
|
-
}
|
|
2163
2233
|
const html = e.clipboardData.getData("text/html");
|
|
2164
|
-
if (html) {
|
|
2165
|
-
exec("insertHTML", false, sanitizeValue(html));
|
|
2166
|
-
return;
|
|
2167
|
-
}
|
|
2168
2234
|
const text = e.clipboardData.getData("text/plain");
|
|
2169
|
-
|
|
2235
|
+
const pasteValue = isPlaintextMode
|
|
2236
|
+
? text
|
|
2237
|
+
: html
|
|
2238
|
+
? sanitizeValue(html)
|
|
2239
|
+
: text;
|
|
2240
|
+
exec(isPlaintextMode ? "insertText" : "insertHTML", false, pasteValue);
|
|
2170
2241
|
};
|
|
2171
2242
|
const handleKeyDown = (e) => {
|
|
2172
2243
|
onKeyDown?.(e);
|
|
2173
|
-
if (
|
|
2244
|
+
if (!isPlaintextMode &&
|
|
2174
2245
|
(e.key === "Backspace" || e.key === "Delete") &&
|
|
2175
2246
|
removeAdjacentMemtionTag(editorRef.current, e.key)) {
|
|
2176
2247
|
e.preventDefault();
|
|
@@ -2207,7 +2278,7 @@ const Editor = (props) => {
|
|
|
2207
2278
|
switch (e.key) {
|
|
2208
2279
|
case "Tab":
|
|
2209
2280
|
e.preventDefault();
|
|
2210
|
-
exec(
|
|
2281
|
+
exec(isRichMode ? "insertHTML" : "insertText", false, isRichMode ? "	" : "\t");
|
|
2211
2282
|
break;
|
|
2212
2283
|
case "Enter":
|
|
2213
2284
|
if (!onEnter)
|
|
@@ -2224,9 +2295,7 @@ const Editor = (props) => {
|
|
|
2224
2295
|
if (getEditorValue(true) === nextValue)
|
|
2225
2296
|
return;
|
|
2226
2297
|
setEditorValue(nextValue);
|
|
2227
|
-
|
|
2228
|
-
editorRef.current.style.height = `${editorRef.current.scrollHeight}px`;
|
|
2229
|
-
}
|
|
2298
|
+
syncHeight();
|
|
2230
2299
|
}, [autosize, mode, value]);
|
|
2231
2300
|
useEffect(() => {
|
|
2232
2301
|
if (!memtionOptions.length) {
|
|
@@ -2238,6 +2307,11 @@ const Editor = (props) => {
|
|
|
2238
2307
|
const handleInput = (e) => {
|
|
2239
2308
|
const rawValue = getEditorValue();
|
|
2240
2309
|
let nextValue = sanitizeValue(rawValue);
|
|
2310
|
+
if (isPlaintextOnMemtionMode &&
|
|
2311
|
+
rawValue !== nextValue &&
|
|
2312
|
+
editorRef.current) {
|
|
2313
|
+
setEditorValue(nextValue);
|
|
2314
|
+
}
|
|
2241
2315
|
if (!nextValue && rawValue && editorRef.current) {
|
|
2242
2316
|
nextValue = "";
|
|
2243
2317
|
setEditorValue(nextValue);
|
|
@@ -2258,9 +2332,7 @@ const Editor = (props) => {
|
|
|
2258
2332
|
setMemtionVisible(true);
|
|
2259
2333
|
}
|
|
2260
2334
|
}
|
|
2261
|
-
|
|
2262
|
-
editorRef.current.style.height = `${editorRef.current.scrollHeight}px`;
|
|
2263
|
-
}
|
|
2335
|
+
syncHeight();
|
|
2264
2336
|
onChange?.(nextValue, e);
|
|
2265
2337
|
};
|
|
2266
2338
|
const handleFocus = (e) => {
|
|
@@ -2301,7 +2373,7 @@ const Editor = (props) => {
|
|
|
2301
2373
|
...style,
|
|
2302
2374
|
[autosize ? "minHeight" : "height"]: height,
|
|
2303
2375
|
width,
|
|
2304
|
-
}, children: [!hideControl && (jsx("div", { className: "i-editor-controls", children: controls })), memtion && (jsx(Memtion$1, { visible: memtionVisible, rect: memtionRect, options: memtionOptions, activeIndex: memtionActiveIndex, onActiveChange: setMemtionActiveIndex, onSelect: insertMemtion })), jsx("div", { ref: handleRef, className: "i-editor-content", "data-placeholder": placeholder, contentEditable:
|
|
2376
|
+
}, children: [!hideControl && (jsx("div", { className: "i-editor-controls", children: controls })), memtion && (jsx(Memtion$1, { visible: memtionVisible, rect: memtionRect, options: memtionOptions, activeIndex: memtionActiveIndex, onActiveChange: setMemtionActiveIndex, onSelect: insertMemtion })), jsx("div", { ref: handleRef, className: "i-editor-content", "data-placeholder": placeholder, contentEditable: isPlaintextMode ? "plaintext-only" : true, onFocus: handleFocus, onBlur: handleBlur, onMouseUp: handleMouseUp, onPaste: handlePaste, onInput: handleInput, onKeyUp: handleKeyUp, onKeyDown: handleKeyDown, ...restProps })] }));
|
|
2305
2377
|
};
|
|
2306
2378
|
|
|
2307
2379
|
const Flex = (props) => {
|
|
@@ -3939,7 +4011,7 @@ const displayValue = (config) => {
|
|
|
3939
4011
|
};
|
|
3940
4012
|
|
|
3941
4013
|
const Select = (props) => {
|
|
3942
|
-
const { ref, type = "text", name, label, value = "", placeholder, options = [], multiple, prepend, append, labelInline, style, className, message, status = "normal", hideClear, hideArrow, maxDisplay, border, filter, tip, filterPlaceholder = "...", popupProps, onSelect, onChange, ...restProps } = props;
|
|
4014
|
+
const { ref, type = "text", name, label, value = "", placeholder, required, options = [], multiple, prepend, append, labelInline, style, className, message, status = "normal", hideClear, hideArrow, maxDisplay, border, filter, tip, filterPlaceholder = "...", popupProps, onSelect, onChange, ...restProps } = props;
|
|
3943
4015
|
const [filterValue, setFilterValue] = useState("");
|
|
3944
4016
|
const [selectedValue, setSelectedValue] = useState(value);
|
|
3945
4017
|
const [active, setActive] = useState(false);
|
|
@@ -4006,11 +4078,11 @@ const Select = (props) => {
|
|
|
4006
4078
|
const text = message ?? tip;
|
|
4007
4079
|
return (jsxs("label", { className: classNames("i-input-label", className, {
|
|
4008
4080
|
"i-input-inline": labelInline,
|
|
4009
|
-
}), style: style, children: [label &&
|
|
4081
|
+
}), style: style, children: [label && (jsxs("span", { className: "i-input-label-text", children: [required && jsx("span", { className: "error", children: "*" }), label] })), jsx(Popup, { position: "bottom", arrow: false, fitSize: true, offset: 0, ...popupProps, visible: active, trigger: "none", onVisibleChange: handleVisibleChange, content: jsx(Options, { options: filterOptions, value: selectedValue, multiple: multiple, filter: !!filter, filterPlaceholder: filterPlaceholder, onSelect: handleSelect, onFilter: handleFilterChange }), children: jsxs("div", { className: classNames("i-input-item", {
|
|
4010
4082
|
[`i-input-${status}`]: status !== "normal",
|
|
4011
4083
|
"i-input-borderless": !border,
|
|
4012
4084
|
"i-input-focus": active,
|
|
4013
|
-
}), onClick: () => setActive(true), children: [prepend, jsx("input", { ref: ref, type:
|
|
4085
|
+
}), onClick: () => setActive(true), children: [prepend, jsx("input", { ref: ref, type: "hidden", value: selectedValue, ...restProps }), multiple ? (hasValue ? (jsx("div", { className: classNames("i-input i-select", {
|
|
4014
4086
|
"i-select-multiple": multiple,
|
|
4015
4087
|
}), children: displayValue({
|
|
4016
4088
|
options: formattedOptions,
|
|
@@ -4018,7 +4090,7 @@ const Select = (props) => {
|
|
|
4018
4090
|
multiple,
|
|
4019
4091
|
maxDisplay,
|
|
4020
4092
|
onSelect: handleSelect,
|
|
4021
|
-
}) })) : (jsx("input", { className:
|
|
4093
|
+
}) })) : (jsx("input", { className: "i-input i-select", placeholder: placeholder, readOnly: true }))) : null, !multiple && (jsx("input", { value: active ? filterValue : displayLabel, className: "i-input i-select", placeholder: displayLabel || placeholder, onChange: handleInputChange, readOnly: !filter })), jsx(Helpericon, { active: !hideArrow, icon: clearable ? undefined : jsx(UnfoldMoreRound, {}), onClick: handleHelperClick }), append] }) }), text && jsx("span", { className: "i-input-message", children: text })] }));
|
|
4022
4094
|
};
|
|
4023
4095
|
|
|
4024
4096
|
const ColorMethods = {
|
|
@@ -4051,7 +4123,7 @@ const Handle = (props) => {
|
|
|
4051
4123
|
};
|
|
4052
4124
|
|
|
4053
4125
|
function ColorPicker(props) {
|
|
4054
|
-
const { value, type = "HEX", disabledAlpha, children, usePanel, handle = "both", placeholder = "Colors", popupProps, onChange, } = props;
|
|
4126
|
+
const { value, type = "HEX", disabledAlpha, children, usePanel, handle = "both", placeholder = "Colors", popupProps, onChange, label, required, ...restProps } = props;
|
|
4055
4127
|
const [colorType, setColorType] = useState(type);
|
|
4056
4128
|
const [colorValue, setColorValue] = useState(value);
|
|
4057
4129
|
const [syncValue, setSyncValue] = useState(value);
|
|
@@ -4093,11 +4165,11 @@ function ColorPicker(props) {
|
|
|
4093
4165
|
}
|
|
4094
4166
|
}, [popupProps?.visible]);
|
|
4095
4167
|
if (usePanel) {
|
|
4096
|
-
return jsx(ColorsPanel, { ...
|
|
4168
|
+
return (jsx(InputContainer, { label: label, required: required, children: jsx(ColorsPanel, { ...restProps, value: value, onChange: onChange }) }));
|
|
4097
4169
|
}
|
|
4098
|
-
return (jsx(Popup, { trigger:
|
|
4099
|
-
|
|
4100
|
-
|
|
4170
|
+
return (jsx(InputContainer, { label: label, required: required, children: jsx(Popup, { trigger: "click", touchable: true, position: "bottom", ...popupProps, visible: visible, content: jsx(ColorsPanel, { ...restProps, value: syncValue, disabledAlpha: disabledAlpha, panelRender: (panel) => {
|
|
4171
|
+
return (jsxs(Fragment, { children: [panel, jsx(Footer, { value: colorValue, type: colorType, onTypeChange: handleTypeChange, onChange: handleValueChange, onOk: handleOk })] }));
|
|
4172
|
+
}, onChange: handleChange, onChangeComplete: handleComplete }), onVisibleChange: handleVisibleChange, children: children ?? (jsx(Handle, { color: value, handle: handle, placeholder: placeholder })) }) }));
|
|
4101
4173
|
}
|
|
4102
4174
|
|
|
4103
4175
|
const Dates = (props) => {
|
|
@@ -4899,14 +4971,104 @@ const Swiper = ((props) => {
|
|
|
4899
4971
|
});
|
|
4900
4972
|
Swiper.Item = Item$1;
|
|
4901
4973
|
|
|
4974
|
+
const TabsContents = (props) => {
|
|
4975
|
+
const { tabs, activeKey, cachedTabKeySet, getContent } = props;
|
|
4976
|
+
return (jsx("div", { className: "i-tab-contents", children: tabs.map((tab, i) => {
|
|
4977
|
+
const key = tab.key ?? `${i}`;
|
|
4978
|
+
const content = getContent(key);
|
|
4979
|
+
const isActive = activeKey === key;
|
|
4980
|
+
const show = isActive || cachedTabKeySet.has(key);
|
|
4981
|
+
return (show && (jsx("div", { className: classNames("i-tab-content", {
|
|
4982
|
+
"i-tab-active": isActive,
|
|
4983
|
+
}), role: "tabpanel", "aria-hidden": !isActive, children: content }, key)));
|
|
4984
|
+
}) }));
|
|
4985
|
+
};
|
|
4986
|
+
var TabsContents$1 = memo(TabsContents);
|
|
4987
|
+
|
|
4988
|
+
const emptyBarStyle = {
|
|
4989
|
+
height: 0,
|
|
4990
|
+
width: 0,
|
|
4991
|
+
};
|
|
4992
|
+
const defaultRenderMore = () => (jsx(Button, { flat: true, square: true, size: "small", children: jsx(Icon, { icon: jsx(MoreHorizRound, {}) }) }));
|
|
4993
|
+
const isSameTabs = (prev, next) => prev.length === next.length &&
|
|
4994
|
+
prev.every((tab, index) => {
|
|
4995
|
+
const target = next[index];
|
|
4996
|
+
return (tab.key === target.key &&
|
|
4997
|
+
tab.title === target.title &&
|
|
4998
|
+
tab.keepDOM === target.keepDOM &&
|
|
4999
|
+
tab.closable === target.closable &&
|
|
5000
|
+
tab.intersecting === target.intersecting);
|
|
5001
|
+
});
|
|
5002
|
+
const getParsedTabs = (items, children) => {
|
|
5003
|
+
const contents = new Map();
|
|
5004
|
+
if (!items) {
|
|
5005
|
+
const tabs = Children.map(children, (node, i) => {
|
|
5006
|
+
const { key, props: nodeProps } = node;
|
|
5007
|
+
const { title, children: tabChildren, content, keepDOM, closable, } = nodeProps;
|
|
5008
|
+
const tabKey = String(key ?? i);
|
|
5009
|
+
contents.set(tabKey, tabChildren ?? content);
|
|
5010
|
+
return {
|
|
5011
|
+
key: tabKey,
|
|
5012
|
+
title,
|
|
5013
|
+
keepDOM,
|
|
5014
|
+
closable,
|
|
5015
|
+
};
|
|
5016
|
+
}) ?? [];
|
|
5017
|
+
return {
|
|
5018
|
+
tabs,
|
|
5019
|
+
contents,
|
|
5020
|
+
keys: new Set(tabs.map((tab) => String(tab.key))),
|
|
5021
|
+
};
|
|
5022
|
+
}
|
|
5023
|
+
const tabs = items.map((item, i) => {
|
|
5024
|
+
if (["string", "number"].includes(typeof item)) {
|
|
5025
|
+
const key = String(item);
|
|
5026
|
+
return { key, title: item };
|
|
5027
|
+
}
|
|
5028
|
+
const key = String(item.key ?? i);
|
|
5029
|
+
contents.set(key, item.content);
|
|
5030
|
+
const { content, ...rest } = item;
|
|
5031
|
+
return {
|
|
5032
|
+
...rest,
|
|
5033
|
+
key,
|
|
5034
|
+
};
|
|
5035
|
+
});
|
|
5036
|
+
return {
|
|
5037
|
+
tabs,
|
|
5038
|
+
contents,
|
|
5039
|
+
keys: new Set(tabs.map((tab) => String(tab.key))),
|
|
5040
|
+
};
|
|
5041
|
+
};
|
|
5042
|
+
|
|
4902
5043
|
const Item = (props) => {
|
|
4903
5044
|
return jsx(Fragment, {});
|
|
4904
5045
|
};
|
|
4905
5046
|
|
|
5047
|
+
const TabsNavs = (props) => {
|
|
5048
|
+
const { tabs, moreTabs, activeKey, vertical, overflow, hideMore, navsJustify = "start", bar, barClass, barStyle, navsRef, renderMore, setNavRef, onOpen, onClose, onMoreTabClick, onKeyAction, } = props;
|
|
5049
|
+
return (jsxs(Fragment, { children: [jsxs("div", { ref: navsRef, className: classNames("i-tab-navs", `justify-${navsJustify}`), role: "tablist", "aria-orientation": vertical ? "vertical" : "horizontal", children: [tabs.map((tab, i) => {
|
|
5050
|
+
const { title, key = `${i}`, closable } = tab;
|
|
5051
|
+
const isActive = activeKey === key;
|
|
5052
|
+
return (jsxs("a", { ref: (node) => setNavRef(i, node), className: classNames("i-tab-nav", {
|
|
5053
|
+
"i-tab-active": isActive,
|
|
5054
|
+
}), role: "tab", tabIndex: isActive ? 0 : -1, "aria-selected": isActive, onClick: () => onOpen(key), onKeyDown: (e) => onKeyAction(e, () => onOpen(key)), children: [title, closable && (jsx(Helpericon, { as: "i", active: true, className: "i-tab-nav-close", role: "button", tabIndex: 0, "aria-label": "\u5173\u95ED\u6807\u7B7E\u9875", onClick: (e) => {
|
|
5055
|
+
e.preventDefault();
|
|
5056
|
+
e.stopPropagation();
|
|
5057
|
+
onClose(key);
|
|
5058
|
+
}, onKeyDown: (e) => onKeyAction(e, () => onClose(key)) }))] }, key));
|
|
5059
|
+
}), bar && (jsx("span", { className: classNames("i-tab-navs-bar", barClass), style: barStyle }))] }), !hideMore && overflow && moreTabs.length > 0 && (jsx(Popup, { arrow: false, position: vertical ? "right" : "bottom", align: "end", touchable: true, hideDelay: 500, content: jsx("div", { className: "i-tabs-morelist pd-4", children: moreTabs.map((tab, i) => {
|
|
5060
|
+
const { key = `${i}`, title } = tab;
|
|
5061
|
+
const isActive = activeKey === key;
|
|
5062
|
+
return (jsx("a", { className: classNames("i-tab-nav", {
|
|
5063
|
+
"i-tab-active": isActive,
|
|
5064
|
+
}), role: "button", tabIndex: 0, onClick: () => onMoreTabClick(key), onKeyDown: (e) => onKeyAction(e, () => onMoreTabClick(key)), children: title }, key));
|
|
5065
|
+
}) }), children: renderMore(moreTabs) }))] }));
|
|
5066
|
+
};
|
|
5067
|
+
var TabsNavs$1 = memo(TabsNavs);
|
|
5068
|
+
|
|
4906
5069
|
const Tabs = ((props) => {
|
|
4907
|
-
const { ref, active, tabs: items, type = "default", prepend, append, children, className, vertical, toggable, navsJustify = "start", bar = true, hideMore, barClass, renderMore =
|
|
5070
|
+
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;
|
|
4908
5071
|
const navRefs = useRef([]);
|
|
4909
|
-
const barRef = useRef(null);
|
|
4910
5072
|
const navsRef = useRef(null);
|
|
4911
5073
|
const contentsRef = useRef(new Map());
|
|
4912
5074
|
const [activeKey, setActiveKey] = useState(active);
|
|
@@ -4923,42 +5085,36 @@ const Tabs = ((props) => {
|
|
|
4923
5085
|
activeKeyRef.current = activeKey;
|
|
4924
5086
|
const prevActiveKeyRef = useRef(prevActiveKey);
|
|
4925
5087
|
prevActiveKeyRef.current = prevActiveKey;
|
|
5088
|
+
const sourceKeysRef = useRef(new Set());
|
|
5089
|
+
const hiddenSourceKeysRef = useRef(new Set());
|
|
5090
|
+
const parsedTabs = useMemo(() => getParsedTabs(items, children), [children, items]);
|
|
4926
5091
|
useEffect(() => {
|
|
4927
|
-
contentsRef.current
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
const { key, props: nodeProps } = node;
|
|
4935
|
-
const { title, children: tabChildren, content, keepDOM, closable, } = nodeProps;
|
|
4936
|
-
const tabKey = String(key ?? i);
|
|
4937
|
-
contentsRef.current.set(tabKey, tabChildren ?? content);
|
|
4938
|
-
return {
|
|
4939
|
-
key: tabKey,
|
|
4940
|
-
title,
|
|
4941
|
-
keepDOM,
|
|
4942
|
-
closable,
|
|
4943
|
-
};
|
|
4944
|
-
}) ?? []);
|
|
4945
|
-
return;
|
|
4946
|
-
}
|
|
4947
|
-
setTabs(items.map((item, i) => {
|
|
4948
|
-
if (["string", "number"].includes(typeof item)) {
|
|
4949
|
-
const key = String(item);
|
|
4950
|
-
return { key, title: item };
|
|
5092
|
+
const prevContents = new Map(contentsRef.current);
|
|
5093
|
+
const nextContents = new Map(parsedTabs.contents);
|
|
5094
|
+
const sourceTabs = parsedTabs.tabs;
|
|
5095
|
+
const sourceKeys = parsedTabs.keys;
|
|
5096
|
+
hiddenSourceKeysRef.current.forEach((key) => {
|
|
5097
|
+
if (!sourceKeys.has(key)) {
|
|
5098
|
+
hiddenSourceKeysRef.current.delete(key);
|
|
4951
5099
|
}
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
const
|
|
4955
|
-
return
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
5100
|
+
});
|
|
5101
|
+
const dynamicTabs = tabsRef.current.filter((tab) => {
|
|
5102
|
+
const key = String(tab.key);
|
|
5103
|
+
return !sourceKeysRef.current.has(key) && !sourceKeys.has(key);
|
|
5104
|
+
});
|
|
5105
|
+
dynamicTabs.forEach((tab) => {
|
|
5106
|
+
const key = String(tab.key);
|
|
5107
|
+
nextContents.set(key, prevContents.get(key));
|
|
5108
|
+
});
|
|
5109
|
+
sourceKeysRef.current = sourceKeys;
|
|
5110
|
+
contentsRef.current = nextContents;
|
|
5111
|
+
const nextTabs = [
|
|
5112
|
+
...sourceTabs.filter((tab) => !hiddenSourceKeysRef.current.has(String(tab.key))),
|
|
5113
|
+
...dynamicTabs,
|
|
5114
|
+
];
|
|
5115
|
+
setTabs((currentTabs) => isSameTabs(currentTabs, nextTabs) ? currentTabs : nextTabs);
|
|
5116
|
+
}, [parsedTabs]);
|
|
5117
|
+
const add = (tab, position) => {
|
|
4962
5118
|
const currentTabs = tabsRef.current;
|
|
4963
5119
|
const tkey = String(tab.key ?? currentTabs.length);
|
|
4964
5120
|
const i = currentTabs.findIndex((t) => t.key === tkey);
|
|
@@ -4968,7 +5124,14 @@ const Tabs = ((props) => {
|
|
|
4968
5124
|
}
|
|
4969
5125
|
contentsRef.current.set(tkey, tab.content);
|
|
4970
5126
|
const { content, ...rest } = tab;
|
|
4971
|
-
setTabs((ts) =>
|
|
5127
|
+
setTabs((ts) => {
|
|
5128
|
+
const nextTabs = [...ts];
|
|
5129
|
+
const index = position === undefined
|
|
5130
|
+
? nextTabs.length
|
|
5131
|
+
: Math.max(0, Math.min(position, nextTabs.length));
|
|
5132
|
+
nextTabs.splice(index, 0, { ...rest, key: tkey });
|
|
5133
|
+
return nextTabs;
|
|
5134
|
+
});
|
|
4972
5135
|
open(tkey);
|
|
4973
5136
|
};
|
|
4974
5137
|
const close = (key) => {
|
|
@@ -4976,7 +5139,12 @@ const Tabs = ((props) => {
|
|
|
4976
5139
|
const i = currentTabs.findIndex((t) => t.key === key);
|
|
4977
5140
|
if (i < 0)
|
|
4978
5141
|
return;
|
|
4979
|
-
|
|
5142
|
+
if (sourceKeysRef.current.has(key)) {
|
|
5143
|
+
hiddenSourceKeysRef.current.add(key);
|
|
5144
|
+
}
|
|
5145
|
+
else {
|
|
5146
|
+
contentsRef.current.delete(key);
|
|
5147
|
+
}
|
|
4980
5148
|
const nextTabs = [...currentTabs];
|
|
4981
5149
|
nextTabs.splice(i, 1);
|
|
4982
5150
|
setTabs(nextTabs);
|
|
@@ -4993,10 +5161,7 @@ const Tabs = ((props) => {
|
|
|
4993
5161
|
onTabChange?.(undefined, activeKey);
|
|
4994
5162
|
setPrevActiveKey(activeKey);
|
|
4995
5163
|
setActiveKey(undefined);
|
|
4996
|
-
setBarStyle(
|
|
4997
|
-
height: 0,
|
|
4998
|
-
width: 0,
|
|
4999
|
-
});
|
|
5164
|
+
setBarStyle(emptyBarStyle);
|
|
5000
5165
|
return;
|
|
5001
5166
|
}
|
|
5002
5167
|
if (nextKey === activeKey) {
|
|
@@ -5004,10 +5169,7 @@ const Tabs = ((props) => {
|
|
|
5004
5169
|
return;
|
|
5005
5170
|
onTabChange?.(undefined, key);
|
|
5006
5171
|
setActiveKey(undefined);
|
|
5007
|
-
setBarStyle(
|
|
5008
|
-
height: 0,
|
|
5009
|
-
width: 0,
|
|
5010
|
-
});
|
|
5172
|
+
setBarStyle(emptyBarStyle);
|
|
5011
5173
|
return;
|
|
5012
5174
|
}
|
|
5013
5175
|
setPrevActiveKey(activeKey);
|
|
@@ -5033,6 +5195,10 @@ const Tabs = ((props) => {
|
|
|
5033
5195
|
open(key);
|
|
5034
5196
|
scrollToTab(key);
|
|
5035
5197
|
};
|
|
5198
|
+
const setNavRef = (index, node) => {
|
|
5199
|
+
navRefs.current[index] = node;
|
|
5200
|
+
};
|
|
5201
|
+
const getContent = (key) => contentsRef.current.get(key);
|
|
5036
5202
|
useEffect(() => {
|
|
5037
5203
|
if (!size || hideMore || !observe || !unobserve)
|
|
5038
5204
|
return;
|
|
@@ -5056,7 +5222,7 @@ const Tabs = ((props) => {
|
|
|
5056
5222
|
return;
|
|
5057
5223
|
}
|
|
5058
5224
|
const observed = [];
|
|
5059
|
-
navRefs.current.
|
|
5225
|
+
navRefs.current.forEach((nav, i) => {
|
|
5060
5226
|
if (!nav)
|
|
5061
5227
|
return;
|
|
5062
5228
|
observed.push(nav);
|
|
@@ -5071,7 +5237,7 @@ const Tabs = ((props) => {
|
|
|
5071
5237
|
});
|
|
5072
5238
|
});
|
|
5073
5239
|
return () => {
|
|
5074
|
-
observed.
|
|
5240
|
+
observed.forEach((el) => unobserve(el));
|
|
5075
5241
|
};
|
|
5076
5242
|
}, [size, hideMore, tabs.length, observe, unobserve]);
|
|
5077
5243
|
useEffect(() => {
|
|
@@ -5093,7 +5259,7 @@ const Tabs = ((props) => {
|
|
|
5093
5259
|
const { offsetHeight, offsetLeft, offsetTop, offsetWidth } = nav;
|
|
5094
5260
|
const isLine = type === "line";
|
|
5095
5261
|
setBarStyle({
|
|
5096
|
-
height: !vertical && isLine ? ".25em" : offsetHeight,
|
|
5262
|
+
height: !vertical && isLine ? ".25em" : offsetHeight * 0.5,
|
|
5097
5263
|
width: vertical && isLine ? ".25em" : offsetWidth,
|
|
5098
5264
|
transform: `translate(${offsetLeft}px, ${offsetTop}px)`,
|
|
5099
5265
|
});
|
|
@@ -5105,7 +5271,8 @@ const Tabs = ((props) => {
|
|
|
5105
5271
|
useEffect(() => {
|
|
5106
5272
|
if (active === undefined || activeKey === active)
|
|
5107
5273
|
return;
|
|
5108
|
-
|
|
5274
|
+
setPrevActiveKey(activeKey);
|
|
5275
|
+
setActiveKey(active);
|
|
5109
5276
|
}, [active]);
|
|
5110
5277
|
useEffect(() => {
|
|
5111
5278
|
if (!navsRef.current || vertical)
|
|
@@ -5134,37 +5301,13 @@ const Tabs = ((props) => {
|
|
|
5134
5301
|
add,
|
|
5135
5302
|
navs: navsRef,
|
|
5136
5303
|
}));
|
|
5137
|
-
const
|
|
5304
|
+
const cachedTabKeySet = useMemo(() => new Set(cachedTabs), [cachedTabs]);
|
|
5305
|
+
const moreTabs = useMemo(() => !hideMore && overflow
|
|
5138
5306
|
? tabs.filter((tab) => tab.intersecting === false)
|
|
5139
|
-
: [];
|
|
5140
|
-
return (jsxs("div", { className: classNames("i-tabs", { flex: vertical, [`i-tabs-${type}`]: type !== "default" }, className), ...rest, children: [jsxs("div", { className: classNames("i-tab-navs-container", {
|
|
5307
|
+
: [], [hideMore, overflow, tabs]);
|
|
5308
|
+
return (jsxs("div", { className: classNames("i-tabs", { flex: vertical, [`i-tabs-${type}`]: type !== "default" }, className), ...rest, children: [jsxs("div", { className: classNames("i-tab-navs-container", navsClass, {
|
|
5141
5309
|
"i-tab-navs-vertical": vertical,
|
|
5142
|
-
}), children: [prepend,
|
|
5143
|
-
const { title, key = `${i}`, closable } = tab;
|
|
5144
|
-
const isActive = activeKey === key;
|
|
5145
|
-
return (jsxs("a", { ref: (ref) => (navRefs.current[i] = ref), className: classNames("i-tab-nav", {
|
|
5146
|
-
"i-tab-active": isActive,
|
|
5147
|
-
}), role: "tab", tabIndex: isActive ? 0 : -1, "aria-selected": isActive, onClick: () => open(key), onKeyDown: (e) => handleKeyAction(e, () => open(key)), children: [title, closable && (jsx(Helpericon, { as: "i", active: true, className: "i-tab-nav-close", role: "button", tabIndex: 0, "aria-label": "\u5173\u95ED\u6807\u7B7E\u9875", onClick: (e) => {
|
|
5148
|
-
e.preventDefault();
|
|
5149
|
-
e.stopPropagation();
|
|
5150
|
-
close(key);
|
|
5151
|
-
}, onKeyDown: (e) => handleKeyAction(e, () => close(key)) }))] }, key));
|
|
5152
|
-
}), bar && (jsx("span", { ref: barRef, className: classNames("i-tab-navs-bar", barClass), style: barStyle }))] }), !hideMore && overflow && moreTabs.length > 0 && (jsx(Popup, { arrow: false, position: vertical ? "right" : "bottom", align: "end", touchable: true, hideDelay: 500, content: jsx("div", { className: "i-tabs-morelist pd-4", children: moreTabs.map((tab, i) => {
|
|
5153
|
-
const { key = `${i}`, title } = tab;
|
|
5154
|
-
const isActive = activeKey === key;
|
|
5155
|
-
return (jsx("a", { className: classNames("i-tab-nav", {
|
|
5156
|
-
"i-tab-active": isActive,
|
|
5157
|
-
}), role: "button", tabIndex: 0, onClick: () => handleMoreTabClick(key), onKeyDown: (e) => handleKeyAction(e, () => handleMoreTabClick(key)), children: title }, key));
|
|
5158
|
-
}) }), children: renderMore(moreTabs) })), append] }), jsx("div", { className: "i-tab-contents", children: tabs.map((tab, i) => {
|
|
5159
|
-
const key = tab.key ?? `${i}`;
|
|
5160
|
-
const content = contentsRef.current.get(key);
|
|
5161
|
-
const isActive = activeKey === key;
|
|
5162
|
-
const show = isActive ||
|
|
5163
|
-
(key !== undefined && cachedTabs.includes(key));
|
|
5164
|
-
return (show && (jsx("div", { className: classNames("i-tab-content", {
|
|
5165
|
-
"i-tab-active": isActive,
|
|
5166
|
-
}), role: "tabpanel", "aria-hidden": !isActive, children: content }, key)));
|
|
5167
|
-
}) })] }));
|
|
5310
|
+
}), children: [prepend, jsx(TabsNavs$1, { tabs: tabs, moreTabs: moreTabs, activeKey: activeKey, vertical: vertical, overflow: overflow, hideMore: hideMore, navsJustify: navsJustify, bar: bar, barClass: barClass, barStyle: barStyle, navsRef: navsRef, renderMore: renderMore, setNavRef: setNavRef, onOpen: open, onClose: close, onMoreTabClick: handleMoreTabClick, onKeyAction: handleKeyAction }), append] }), jsx(TabsContents$1, { tabs: tabs, activeKey: activeKey, cachedTabKeySet: cachedTabKeySet, getContent: getContent })] }));
|
|
5168
5311
|
});
|
|
5169
5312
|
Tabs.Item = Item;
|
|
5170
5313
|
|