@ioca/react 1.5.4 → 1.5.6
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 +19 -37
- 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 +99 -6
- 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/tabs.js +1 -1
- 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 +20 -38
- 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 +99 -7
- 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/tabs.js +1 -1
- package/lib/es/components/tabs/tabs.js.map +1 -1
- package/lib/index.js +162 -80
- package/lib/types/components/editor/type.d.ts +1 -1
- package/lib/types/components/picker/type.d.ts +3 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -2,10 +2,10 @@ 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
|
-
import xss
|
|
8
|
+
import xss from 'xss';
|
|
9
9
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
10
10
|
import PubSub from 'pubsub-js';
|
|
11
11
|
import { findAll } from 'highlight-words-core';
|
|
@@ -1849,70 +1849,90 @@ const exec = (a, b, c) => {
|
|
|
1849
1849
|
return;
|
|
1850
1850
|
return document.execCommand(a, b, c);
|
|
1851
1851
|
};
|
|
1852
|
+
const escapeHtmlAttr$1 = (value) => value
|
|
1853
|
+
.replaceAll("&", "&")
|
|
1854
|
+
.replaceAll('"', """)
|
|
1855
|
+
.replaceAll("<", "<")
|
|
1856
|
+
.replaceAll(">", ">");
|
|
1852
1857
|
const xssOptions = {
|
|
1853
1858
|
onIgnoreTagAttr(tag, name, value) {
|
|
1854
1859
|
if (["class", "contenteditable"].includes(name)) {
|
|
1855
|
-
return name + '="' +
|
|
1860
|
+
return name + '="' + escapeHtmlAttr$1(value) + '"';
|
|
1856
1861
|
}
|
|
1857
1862
|
if (["data-", "style"].includes(name.substring(0, 5))) {
|
|
1858
|
-
return name + '="' +
|
|
1863
|
+
return name + '="' + escapeHtmlAttr$1(value) + '"';
|
|
1859
1864
|
}
|
|
1860
1865
|
},
|
|
1861
1866
|
};
|
|
1862
1867
|
const handleMouseDown = (e) => {
|
|
1863
1868
|
e.preventDefault();
|
|
1864
1869
|
};
|
|
1865
|
-
const
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
},
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
onClick: () => exec("italic"),
|
|
1873
|
-
},
|
|
1874
|
-
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",
|
|
1875
1877
|
icon: jsx(FormatUnderlinedRound, {}),
|
|
1876
1878
|
onClick: () => exec("underline"),
|
|
1877
1879
|
},
|
|
1878
|
-
|
|
1880
|
+
{
|
|
1881
|
+
key: "strike",
|
|
1879
1882
|
icon: jsx(StrikethroughSRound, {}),
|
|
1880
1883
|
onClick: () => exec("strikeThrough"),
|
|
1881
1884
|
},
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
onClick: () => exec("redo"),
|
|
1885
|
-
},
|
|
1886
|
-
undo: {
|
|
1887
|
-
icon: jsx(UndoRound, {}),
|
|
1888
|
-
onClick: () => exec("undo"),
|
|
1889
|
-
},
|
|
1890
|
-
clear: {
|
|
1885
|
+
{
|
|
1886
|
+
key: "clear",
|
|
1891
1887
|
icon: jsx(ClearAllRound, {}),
|
|
1892
1888
|
onClick: () => exec("removeFormat"),
|
|
1893
1889
|
},
|
|
1894
|
-
};
|
|
1895
|
-
const defaultKeys = [
|
|
1896
|
-
"undo",
|
|
1897
|
-
"redo",
|
|
1898
|
-
"bold",
|
|
1899
|
-
"italic",
|
|
1900
|
-
"underline",
|
|
1901
|
-
"strike",
|
|
1902
|
-
"clear",
|
|
1903
1890
|
];
|
|
1904
|
-
const typedFnMap = fnMap;
|
|
1905
1891
|
function getControls(options) {
|
|
1906
1892
|
const { controlBtnProps, addtionControls, getSelection } = options;
|
|
1907
|
-
const controls =
|
|
1908
|
-
const { icon, onClick } = typedFnMap[k];
|
|
1909
|
-
return (jsx(Button, { ...controlBtnProps, onMouseDown: handleMouseDown, onClick: onClick, children: jsx(Icon, { icon: icon }) }, k));
|
|
1910
|
-
});
|
|
1893
|
+
const controls = defaultControls.map(({ key, icon, onClick }) => (jsx(Button, { ...controlBtnProps, onMouseDown: handleMouseDown, onClick: onClick, children: jsx(Icon, { icon: icon }) }, key)));
|
|
1911
1894
|
const extControls = (addtionControls ?? []).map((item, index) => (jsx(Button, { ...controlBtnProps, onMouseDown: handleMouseDown, onClick: (e) => item.onClick?.(getSelection(), e), children: item.icon }, `addtion-${index}`)));
|
|
1912
1895
|
return [...controls, ...extControls];
|
|
1913
1896
|
}
|
|
1914
1897
|
|
|
1915
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
|
+
]);
|
|
1931
|
+
const escapeHtmlAttr = (value) => value
|
|
1932
|
+
.replaceAll("&", "&")
|
|
1933
|
+
.replaceAll('"', """)
|
|
1934
|
+
.replaceAll("<", "<")
|
|
1935
|
+
.replaceAll(">", ">");
|
|
1916
1936
|
const getInsertNode = (memtion, option) => memtion?.insert?.(option) ?? option.value;
|
|
1917
1937
|
const getInsertText = (memtion, option) => {
|
|
1918
1938
|
const nextNode = getInsertNode(memtion, option);
|
|
@@ -1927,7 +1947,7 @@ const getInsertHtml = (memtion, option, sanitizeValue) => {
|
|
|
1927
1947
|
return "";
|
|
1928
1948
|
}
|
|
1929
1949
|
const content = sanitizeValue(renderToStaticMarkup(jsx(Fragment, { children: nextNode })));
|
|
1930
|
-
return `<span class="${MEMTION_TAG_CLASS_NAME}" contenteditable="false" data-memtion-value="${
|
|
1950
|
+
return `<span class="${MEMTION_TAG_CLASS_NAME}" contenteditable="false" data-memtion-value="${escapeHtmlAttr(String(option.value))}">${content}</span>`;
|
|
1931
1951
|
};
|
|
1932
1952
|
const getSelectionRect = (range) => {
|
|
1933
1953
|
if (!range)
|
|
@@ -1958,14 +1978,11 @@ const insertMemtionOption = ({ editor, range, mode, memtion, option, sanitizeVal
|
|
|
1958
1978
|
const html = getInsertHtml(memtion, option, sanitizeValue);
|
|
1959
1979
|
const fragment = nextRange.createContextualFragment(html);
|
|
1960
1980
|
const lastNode = fragment.lastChild;
|
|
1961
|
-
const spacing = document.createTextNode(" ");
|
|
1962
1981
|
nextRange.insertNode(fragment);
|
|
1963
1982
|
if (lastNode) {
|
|
1964
1983
|
nextRange.setStartAfter(lastNode);
|
|
1965
1984
|
nextRange.collapse(true);
|
|
1966
1985
|
}
|
|
1967
|
-
nextRange.insertNode(spacing);
|
|
1968
|
-
nextRange.setStartAfter(spacing);
|
|
1969
1986
|
}
|
|
1970
1987
|
nextRange.collapse(true);
|
|
1971
1988
|
browserSelection.removeAllRanges();
|
|
@@ -1995,6 +2012,60 @@ const filterMemtionOptions = (options, keyword) => {
|
|
|
1995
2012
|
};
|
|
1996
2013
|
const isMemtionTag = (node) => node instanceof HTMLElement &&
|
|
1997
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
|
+
};
|
|
1998
2069
|
const getAdjacentMemtionTag = (range, direction) => {
|
|
1999
2070
|
const { startContainer, startOffset } = range;
|
|
2000
2071
|
if (startContainer.nodeType === Node.TEXT_NODE) {
|
|
@@ -2052,11 +2123,15 @@ const Memtion = (props) => {
|
|
|
2052
2123
|
if (!visible || !rect || !options?.length) {
|
|
2053
2124
|
return null;
|
|
2054
2125
|
}
|
|
2055
|
-
|
|
2126
|
+
const content = (jsx(List$1, { className: "i-editor-memtion", type: "option", style: {
|
|
2056
2127
|
position: "fixed",
|
|
2057
2128
|
top: rect.bottom,
|
|
2058
2129
|
left: rect.left,
|
|
2059
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);
|
|
2060
2135
|
};
|
|
2061
2136
|
var Memtion$1 = memo(Memtion);
|
|
2062
2137
|
|
|
@@ -2071,18 +2146,28 @@ const Editor = (props) => {
|
|
|
2071
2146
|
const selectionRef = useRef(null);
|
|
2072
2147
|
const memtionTriggerRangeRef = useRef(null);
|
|
2073
2148
|
const pendingMemtionRef = useRef(false);
|
|
2149
|
+
const isPlaintextMode = mode === "plaintext";
|
|
2150
|
+
const isRichMode = mode === "rich";
|
|
2151
|
+
const isPlaintextOnMemtionMode = mode === "plaintextOnMemtion";
|
|
2074
2152
|
const [memtionVisible, setMemtionVisible] = useState(false);
|
|
2075
2153
|
const [memtionRect, setMemtionRect] = useState(null);
|
|
2076
2154
|
const [memtionKeyword, setMemtionKeyword] = useState("");
|
|
2077
2155
|
const [memtionActiveIndex, setMemtionActiveIndex] = useState(0);
|
|
2078
2156
|
const memtionOptions = useMemo(() => filterMemtionOptions(memtion?.options ?? [], memtionKeyword), [memtion?.options, memtionKeyword]);
|
|
2079
2157
|
const sanitizeValue = (nextValue) => {
|
|
2080
|
-
if (
|
|
2158
|
+
if (isPlaintextMode) {
|
|
2081
2159
|
return nextValue === "\n" ? "" : nextValue;
|
|
2082
2160
|
}
|
|
2083
|
-
const safeHtml =
|
|
2161
|
+
const safeHtml = isPlaintextOnMemtionMode
|
|
2162
|
+
? sanitizePlaintextOnMemtionHtml(xss(nextValue, xssOptions))
|
|
2163
|
+
: xss(nextValue, xssOptions);
|
|
2084
2164
|
return safeHtml === "<br>" ? "" : safeHtml;
|
|
2085
2165
|
};
|
|
2166
|
+
const syncHeight = () => {
|
|
2167
|
+
if (autosize && editorRef.current) {
|
|
2168
|
+
editorRef.current.style.height = `${editorRef.current.scrollHeight}px`;
|
|
2169
|
+
}
|
|
2170
|
+
};
|
|
2086
2171
|
const rememberSelection = () => {
|
|
2087
2172
|
if (!editorRef.current)
|
|
2088
2173
|
return;
|
|
@@ -2102,18 +2187,18 @@ const Editor = (props) => {
|
|
|
2102
2187
|
if (!editorRef.current)
|
|
2103
2188
|
return;
|
|
2104
2189
|
const safeValue = sanitizeValue(nextValue);
|
|
2105
|
-
if (
|
|
2190
|
+
if (isPlaintextMode) {
|
|
2106
2191
|
editorRef.current.textContent = safeValue;
|
|
2107
2192
|
return;
|
|
2108
2193
|
}
|
|
2109
2194
|
editorRef.current.innerHTML = safeValue;
|
|
2110
2195
|
};
|
|
2111
2196
|
const getEditorValue = (sanitize = false) => {
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2197
|
+
const nextValue = !editorRef.current
|
|
2198
|
+
? ""
|
|
2199
|
+
: isPlaintextMode
|
|
2200
|
+
? (editorRef.current.textContent ?? "")
|
|
2201
|
+
: editorRef.current.innerHTML;
|
|
2117
2202
|
return sanitize ? sanitizeValue(nextValue) : nextValue;
|
|
2118
2203
|
};
|
|
2119
2204
|
const hideMemtion = () => {
|
|
@@ -2145,22 +2230,18 @@ const Editor = (props) => {
|
|
|
2145
2230
|
if (e.defaultPrevented)
|
|
2146
2231
|
return;
|
|
2147
2232
|
e.preventDefault();
|
|
2148
|
-
if (mode === "plaintext") {
|
|
2149
|
-
const text = e.clipboardData.getData("text/plain");
|
|
2150
|
-
exec("insertText", false, text);
|
|
2151
|
-
return;
|
|
2152
|
-
}
|
|
2153
2233
|
const html = e.clipboardData.getData("text/html");
|
|
2154
|
-
if (html) {
|
|
2155
|
-
exec("insertHTML", false, sanitizeValue(html));
|
|
2156
|
-
return;
|
|
2157
|
-
}
|
|
2158
2234
|
const text = e.clipboardData.getData("text/plain");
|
|
2159
|
-
|
|
2235
|
+
const pasteValue = isPlaintextMode
|
|
2236
|
+
? text
|
|
2237
|
+
: html
|
|
2238
|
+
? sanitizeValue(html)
|
|
2239
|
+
: text;
|
|
2240
|
+
exec(isPlaintextMode ? "insertText" : "insertHTML", false, pasteValue);
|
|
2160
2241
|
};
|
|
2161
2242
|
const handleKeyDown = (e) => {
|
|
2162
2243
|
onKeyDown?.(e);
|
|
2163
|
-
if (
|
|
2244
|
+
if (!isPlaintextMode &&
|
|
2164
2245
|
(e.key === "Backspace" || e.key === "Delete") &&
|
|
2165
2246
|
removeAdjacentMemtionTag(editorRef.current, e.key)) {
|
|
2166
2247
|
e.preventDefault();
|
|
@@ -2197,7 +2278,7 @@ const Editor = (props) => {
|
|
|
2197
2278
|
switch (e.key) {
|
|
2198
2279
|
case "Tab":
|
|
2199
2280
|
e.preventDefault();
|
|
2200
|
-
exec(
|
|
2281
|
+
exec(isRichMode ? "insertHTML" : "insertText", false, isRichMode ? "	" : "\t");
|
|
2201
2282
|
break;
|
|
2202
2283
|
case "Enter":
|
|
2203
2284
|
if (!onEnter)
|
|
@@ -2214,9 +2295,7 @@ const Editor = (props) => {
|
|
|
2214
2295
|
if (getEditorValue(true) === nextValue)
|
|
2215
2296
|
return;
|
|
2216
2297
|
setEditorValue(nextValue);
|
|
2217
|
-
|
|
2218
|
-
editorRef.current.style.height = `${editorRef.current.scrollHeight}px`;
|
|
2219
|
-
}
|
|
2298
|
+
syncHeight();
|
|
2220
2299
|
}, [autosize, mode, value]);
|
|
2221
2300
|
useEffect(() => {
|
|
2222
2301
|
if (!memtionOptions.length) {
|
|
@@ -2228,6 +2307,11 @@ const Editor = (props) => {
|
|
|
2228
2307
|
const handleInput = (e) => {
|
|
2229
2308
|
const rawValue = getEditorValue();
|
|
2230
2309
|
let nextValue = sanitizeValue(rawValue);
|
|
2310
|
+
if (isPlaintextOnMemtionMode &&
|
|
2311
|
+
rawValue !== nextValue &&
|
|
2312
|
+
editorRef.current) {
|
|
2313
|
+
setEditorValue(nextValue);
|
|
2314
|
+
}
|
|
2231
2315
|
if (!nextValue && rawValue && editorRef.current) {
|
|
2232
2316
|
nextValue = "";
|
|
2233
2317
|
setEditorValue(nextValue);
|
|
@@ -2248,9 +2332,7 @@ const Editor = (props) => {
|
|
|
2248
2332
|
setMemtionVisible(true);
|
|
2249
2333
|
}
|
|
2250
2334
|
}
|
|
2251
|
-
|
|
2252
|
-
editorRef.current.style.height = `${editorRef.current.scrollHeight}px`;
|
|
2253
|
-
}
|
|
2335
|
+
syncHeight();
|
|
2254
2336
|
onChange?.(nextValue, e);
|
|
2255
2337
|
};
|
|
2256
2338
|
const handleFocus = (e) => {
|
|
@@ -2291,7 +2373,7 @@ const Editor = (props) => {
|
|
|
2291
2373
|
...style,
|
|
2292
2374
|
[autosize ? "minHeight" : "height"]: height,
|
|
2293
2375
|
width,
|
|
2294
|
-
}, 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 })] }));
|
|
2295
2377
|
};
|
|
2296
2378
|
|
|
2297
2379
|
const Flex = (props) => {
|
|
@@ -3929,7 +4011,7 @@ const displayValue = (config) => {
|
|
|
3929
4011
|
};
|
|
3930
4012
|
|
|
3931
4013
|
const Select = (props) => {
|
|
3932
|
-
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;
|
|
3933
4015
|
const [filterValue, setFilterValue] = useState("");
|
|
3934
4016
|
const [selectedValue, setSelectedValue] = useState(value);
|
|
3935
4017
|
const [active, setActive] = useState(false);
|
|
@@ -3996,11 +4078,11 @@ const Select = (props) => {
|
|
|
3996
4078
|
const text = message ?? tip;
|
|
3997
4079
|
return (jsxs("label", { className: classNames("i-input-label", className, {
|
|
3998
4080
|
"i-input-inline": labelInline,
|
|
3999
|
-
}), 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", {
|
|
4000
4082
|
[`i-input-${status}`]: status !== "normal",
|
|
4001
4083
|
"i-input-borderless": !border,
|
|
4002
4084
|
"i-input-focus": active,
|
|
4003
|
-
}), 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", {
|
|
4004
4086
|
"i-select-multiple": multiple,
|
|
4005
4087
|
}), children: displayValue({
|
|
4006
4088
|
options: formattedOptions,
|
|
@@ -4008,7 +4090,7 @@ const Select = (props) => {
|
|
|
4008
4090
|
multiple,
|
|
4009
4091
|
maxDisplay,
|
|
4010
4092
|
onSelect: handleSelect,
|
|
4011
|
-
}) })) : (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 })] }));
|
|
4012
4094
|
};
|
|
4013
4095
|
|
|
4014
4096
|
const ColorMethods = {
|
|
@@ -4041,7 +4123,7 @@ const Handle = (props) => {
|
|
|
4041
4123
|
};
|
|
4042
4124
|
|
|
4043
4125
|
function ColorPicker(props) {
|
|
4044
|
-
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;
|
|
4045
4127
|
const [colorType, setColorType] = useState(type);
|
|
4046
4128
|
const [colorValue, setColorValue] = useState(value);
|
|
4047
4129
|
const [syncValue, setSyncValue] = useState(value);
|
|
@@ -4083,11 +4165,11 @@ function ColorPicker(props) {
|
|
|
4083
4165
|
}
|
|
4084
4166
|
}, [popupProps?.visible]);
|
|
4085
4167
|
if (usePanel) {
|
|
4086
|
-
return jsx(ColorsPanel, { ...
|
|
4168
|
+
return (jsx(InputContainer, { label: label, required: required, children: jsx(ColorsPanel, { ...restProps, value: value, onChange: onChange }) }));
|
|
4087
4169
|
}
|
|
4088
|
-
return (jsx(Popup, { trigger:
|
|
4089
|
-
|
|
4090
|
-
|
|
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 })) }) }));
|
|
4091
4173
|
}
|
|
4092
4174
|
|
|
4093
4175
|
const Dates = (props) => {
|
|
@@ -5083,7 +5165,7 @@ const Tabs = ((props) => {
|
|
|
5083
5165
|
const { offsetHeight, offsetLeft, offsetTop, offsetWidth } = nav;
|
|
5084
5166
|
const isLine = type === "line";
|
|
5085
5167
|
setBarStyle({
|
|
5086
|
-
height: !vertical && isLine ? ".25em" :
|
|
5168
|
+
height: !vertical && isLine ? ".25em" : ".8em",
|
|
5087
5169
|
width: vertical && isLine ? ".25em" : offsetWidth,
|
|
5088
5170
|
transform: `translate(${offsetLeft}px, ${offsetTop}px)`,
|
|
5089
5171
|
});
|
|
@@ -20,7 +20,7 @@ interface IEditor extends Omit<HTMLAttributes<HTMLDivElement>, "onInput" | "onCh
|
|
|
20
20
|
width?: string | number;
|
|
21
21
|
height?: string | number;
|
|
22
22
|
autosize?: boolean;
|
|
23
|
-
mode?: "rich" | "plaintext";
|
|
23
|
+
mode?: "rich" | "plaintext" | "plaintextOnMemtion";
|
|
24
24
|
hideControl?: boolean;
|
|
25
25
|
addtionControls?: IEditorAddtionControl[];
|
|
26
26
|
memtion?: IEditorMemtion;
|
|
@@ -27,8 +27,10 @@ interface ITimePicker extends BaseInput, IInput {
|
|
|
27
27
|
renderItem?: (number: number, active: boolean, unit: "hour" | "minute" | "second") => ReactNode;
|
|
28
28
|
popupProps?: IPopup;
|
|
29
29
|
}
|
|
30
|
-
interface IColorPicker extends ColorPickerProps {
|
|
30
|
+
interface IColorPicker extends Omit<ColorPickerProps, "value" | "onChange"> {
|
|
31
31
|
value?: any;
|
|
32
|
+
label?: ReactNode;
|
|
33
|
+
required?: boolean;
|
|
32
34
|
type?: "HEX" | "RGB" | "HSB";
|
|
33
35
|
children?: ReactNode;
|
|
34
36
|
popupProps?: IPopup;
|