@ioca/react 1.5.5 → 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.
Files changed (31) hide show
  1. package/lib/cjs/components/editor/controls.js +12 -34
  2. package/lib/cjs/components/editor/controls.js.map +1 -1
  3. package/lib/cjs/components/editor/editor.js +34 -27
  4. package/lib/cjs/components/editor/editor.js.map +1 -1
  5. package/lib/cjs/components/editor/memtion.js +93 -4
  6. package/lib/cjs/components/editor/memtion.js.map +1 -1
  7. package/lib/cjs/components/picker/colors/index.js +6 -5
  8. package/lib/cjs/components/picker/colors/index.js.map +1 -1
  9. package/lib/cjs/components/select/select.js +4 -4
  10. package/lib/cjs/components/select/select.js.map +1 -1
  11. package/lib/cjs/components/tabs/tabs.js +1 -1
  12. package/lib/cjs/components/tabs/tabs.js.map +1 -1
  13. package/lib/css/index.css +1 -1
  14. package/lib/css/index.css.map +1 -1
  15. package/lib/css/reset.css +2 -2
  16. package/lib/es/components/editor/controls.js +13 -35
  17. package/lib/es/components/editor/controls.js.map +1 -1
  18. package/lib/es/components/editor/editor.js +35 -28
  19. package/lib/es/components/editor/editor.js.map +1 -1
  20. package/lib/es/components/editor/memtion.js +93 -5
  21. package/lib/es/components/editor/memtion.js.map +1 -1
  22. package/lib/es/components/picker/colors/index.js +6 -5
  23. package/lib/es/components/picker/colors/index.js.map +1 -1
  24. package/lib/es/components/select/select.js +4 -4
  25. package/lib/es/components/select/select.js.map +1 -1
  26. package/lib/es/components/tabs/tabs.js +1 -1
  27. package/lib/es/components/tabs/tabs.js.map +1 -1
  28. package/lib/index.js +148 -76
  29. package/lib/types/components/editor/type.d.ts +1 -1
  30. package/lib/types/components/picker/type.d.ts +3 -1
  31. 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, ClearAllRound, UndoRound, RedoRound, StrikethroughSRound, FormatUnderlinedRound, FormatItalicRound, FormatBoldRound, 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';
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 fnMap = {
1871
- bold: {
1872
- icon: jsx(FormatBoldRound, {}),
1873
- onClick: () => exec("bold"),
1874
- },
1875
- italic: {
1876
- icon: jsx(FormatItalicRound, {}),
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
- strike: {
1880
+ {
1881
+ key: "strike",
1884
1882
  icon: jsx(StrikethroughSRound, {}),
1885
1883
  onClick: () => exec("strikeThrough"),
1886
1884
  },
1887
- redo: {
1888
- icon: jsx(RedoRound, {}),
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 = defaultKeys.map((k) => {
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
- return (jsx(List$1, { className: "i-editor-memtion", type: "option", style: {
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 (mode === "plaintext") {
2158
+ if (isPlaintextMode) {
2091
2159
  return nextValue === "\n" ? "" : nextValue;
2092
2160
  }
2093
- const safeHtml = xss(nextValue, xssOptions);
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 (mode === "plaintext") {
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
- if (!editorRef.current)
2123
- return "";
2124
- const nextValue = mode === "plaintext"
2125
- ? (editorRef.current.textContent ?? "")
2126
- : editorRef.current.innerHTML;
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
- exec("insertText", false, text);
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 (mode === "rich" &&
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(mode === "plaintext" ? "insertText" : "insertHTML", false, mode === "plaintext" ? "\t" : "&#09;");
2281
+ exec(isRichMode ? "insertHTML" : "insertText", false, isRichMode ? "&#09;" : "\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
- if (autosize) {
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
- if (autosize && editorRef.current) {
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: mode === "plaintext" ? "plaintext-only" : true, onFocus: handleFocus, onBlur: handleBlur, onMouseUp: handleMouseUp, onPaste: handlePaste, onInput: handleInput, onKeyUp: handleKeyUp, onKeyDown: handleKeyDown, ...restProps })] }));
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 && jsx("span", { className: 'i-input-label-text', 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", {
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: 'hidden', value: selectedValue, ...restProps }), multiple ? (hasValue ? (jsx("div", { className: classNames("i-input i-select", {
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: '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 })] }));
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, { ...props });
4168
+ return (jsx(InputContainer, { label: label, required: required, children: jsx(ColorsPanel, { ...restProps, value: value, onChange: onChange }) }));
4097
4169
  }
4098
- return (jsx(Popup, { trigger: 'click', touchable: true, position: 'bottom', ...popupProps, visible: visible, content: jsx(ColorsPanel, { value: syncValue, disabledAlpha: disabledAlpha, panelRender: (panel) => {
4099
- return (jsxs(Fragment, { children: [panel, jsx(Footer, { value: colorValue, type: colorType, onTypeChange: handleTypeChange, onChange: handleValueChange, onOk: handleOk })] }));
4100
- }, onChange: handleChange, onChangeComplete: handleComplete }), onVisibleChange: handleVisibleChange, children: children ?? (jsx(Handle, { color: value, handle: handle, placeholder: placeholder })) }));
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) => {
@@ -5093,7 +5165,7 @@ const Tabs = ((props) => {
5093
5165
  const { offsetHeight, offsetLeft, offsetTop, offsetWidth } = nav;
5094
5166
  const isLine = type === "line";
5095
5167
  setBarStyle({
5096
- height: !vertical && isLine ? ".25em" : offsetHeight,
5168
+ height: !vertical && isLine ? ".25em" : ".8em",
5097
5169
  width: vertical && isLine ? ".25em" : offsetWidth,
5098
5170
  transform: `translate(${offsetLeft}px, ${offsetTop}px)`,
5099
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ioca/react",
3
- "version": "1.5.05",
3
+ "version": "1.5.06",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite",