@rufous/ui 0.3.62 → 0.3.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.cjs +106 -17
- package/dist/main.css +19 -0
- package/dist/main.js +107 -18
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -2762,28 +2762,55 @@ var TextField = (0, import_react11.forwardRef)(({
|
|
|
2762
2762
|
className
|
|
2763
2763
|
].filter(Boolean).join(" ");
|
|
2764
2764
|
const internalRef = import_react11.default.useRef(null);
|
|
2765
|
+
const numberMin = type === "number" ? slotProps?.input?.min ?? props.min : void 0;
|
|
2766
|
+
const numberMax = type === "number" ? slotProps?.input?.max ?? props.max : void 0;
|
|
2767
|
+
const setNativeValue = (val) => {
|
|
2768
|
+
if (!internalRef.current) return;
|
|
2769
|
+
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
|
|
2770
|
+
setter?.call(internalRef.current, val);
|
|
2771
|
+
};
|
|
2772
|
+
const emitChange = (e, numericValue) => {
|
|
2773
|
+
const syntheticEvent = Object.assign({}, e, {
|
|
2774
|
+
target: Object.assign({}, e.target, { value: numericValue }),
|
|
2775
|
+
currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
|
|
2776
|
+
});
|
|
2777
|
+
onChange?.(syntheticEvent);
|
|
2778
|
+
};
|
|
2765
2779
|
const handleChange = (e) => {
|
|
2766
2780
|
if (type === "number") {
|
|
2767
|
-
|
|
2768
|
-
const inputMax = slotProps?.input?.max ?? props.max;
|
|
2781
|
+
let raw = e.target.value;
|
|
2769
2782
|
const inputMaxLength = slotProps?.input?.maxLength ?? props.maxLength;
|
|
2770
2783
|
if (inputMaxLength != null) {
|
|
2771
2784
|
const digits = raw.replace(/[^0-9]/g, "");
|
|
2772
2785
|
if (digits.length > Number(inputMaxLength)) return;
|
|
2773
2786
|
}
|
|
2774
|
-
if (
|
|
2775
|
-
|
|
2787
|
+
if (numberMax != null && raw !== "" && Number(raw) > Number(numberMax)) {
|
|
2788
|
+
raw = String(numberMax);
|
|
2789
|
+
setNativeValue(raw);
|
|
2776
2790
|
}
|
|
2777
|
-
|
|
2778
|
-
const syntheticEvent = Object.assign({}, e, {
|
|
2779
|
-
target: Object.assign({}, e.target, { value: numericValue }),
|
|
2780
|
-
currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
|
|
2781
|
-
});
|
|
2782
|
-
onChange?.(syntheticEvent);
|
|
2791
|
+
emitChange(e, raw === "" ? "" : Number(raw));
|
|
2783
2792
|
return;
|
|
2784
2793
|
}
|
|
2785
2794
|
onChange?.(e);
|
|
2786
2795
|
};
|
|
2796
|
+
const handleBlur = (e) => {
|
|
2797
|
+
if (type === "number") {
|
|
2798
|
+
const raw = e.target.value;
|
|
2799
|
+
if (raw !== "") {
|
|
2800
|
+
const n = Number(raw);
|
|
2801
|
+
if (!isNaN(n)) {
|
|
2802
|
+
let clamped = n;
|
|
2803
|
+
if (numberMin != null && clamped < Number(numberMin)) clamped = Number(numberMin);
|
|
2804
|
+
if (numberMax != null && clamped > Number(numberMax)) clamped = Number(numberMax);
|
|
2805
|
+
if (clamped !== n) {
|
|
2806
|
+
setNativeValue(String(clamped));
|
|
2807
|
+
emitChange(e, clamped);
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
onBlur?.(e);
|
|
2813
|
+
};
|
|
2787
2814
|
const triggerChange = () => {
|
|
2788
2815
|
if (internalRef.current) {
|
|
2789
2816
|
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
|
|
@@ -2798,9 +2825,10 @@ var TextField = (0, import_react11.forwardRef)(({
|
|
|
2798
2825
|
const stepBy = (delta) => {
|
|
2799
2826
|
if (!internalRef.current) return;
|
|
2800
2827
|
const step = Number(stepProp ?? (numberVariant ? STEP_BY_VARIANT[numberVariant] : 1));
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2828
|
+
let newVal = (parseFloat(internalRef.current.value) || 0) + delta * step;
|
|
2829
|
+
if (numberMax != null && newVal > Number(numberMax)) newVal = Number(numberMax);
|
|
2830
|
+
if (numberMin != null && newVal < Number(numberMin)) newVal = Number(numberMin);
|
|
2831
|
+
setNativeValue(String(newVal));
|
|
2804
2832
|
triggerChange();
|
|
2805
2833
|
};
|
|
2806
2834
|
const handleIncrement = (e) => {
|
|
@@ -2872,7 +2900,8 @@ var TextField = (0, import_react11.forwardRef)(({
|
|
|
2872
2900
|
readOnly,
|
|
2873
2901
|
...slotProps?.input,
|
|
2874
2902
|
...props,
|
|
2875
|
-
onChange: handleChange
|
|
2903
|
+
onChange: handleChange,
|
|
2904
|
+
onBlur: handleBlur
|
|
2876
2905
|
}
|
|
2877
2906
|
), InputProps?.endAdornment && /* @__PURE__ */ import_react11.default.createElement("div", { className: "rf-text-field__adornment rf-text-field__adornment--end" }, InputProps.endAdornment), !isTextarea && type === "number" && !disabled && !readOnly && /* @__PURE__ */ import_react11.default.createElement("div", { className: "rf-text-field__number-controls" }, /* @__PURE__ */ import_react11.default.createElement("button", { type: "button", tabIndex: -1, onClick: handleIncrement, className: "rf-text-field__number-btn" }, /* @__PURE__ */ import_react11.default.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ import_react11.default.createElement("path", { d: "M4 0L8 5H0L4 0Z" }))), /* @__PURE__ */ import_react11.default.createElement("button", { type: "button", tabIndex: -1, onClick: handleDecrement, className: "rf-text-field__number-btn", style: { marginTop: 2 } }, /* @__PURE__ */ import_react11.default.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ import_react11.default.createElement("path", { d: "M4 5L0 0H8L4 5Z" })))), hasLabel && /* @__PURE__ */ import_react11.default.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, " ", required && /* @__PURE__ */ import_react11.default.createElement("span", { className: "rf-text-field__asterisk" }, "*")), variant === "outlined" && /* @__PURE__ */ import_react11.default.createElement("fieldset", { className: "rf-text-field__notch" }, hasLabel ? /* @__PURE__ */ import_react11.default.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ import_react11.default.createElement("span", null, label, " ", required ? "*" : "")) : /* @__PURE__ */ import_react11.default.createElement("legend", { className: "rf-text-field__legend--empty" }))), helperText && /* @__PURE__ */ import_react11.default.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
|
|
2878
2907
|
});
|
|
@@ -13534,6 +13563,15 @@ var IconCheck = () => /* @__PURE__ */ React197.createElement("svg", { ...s }, /*
|
|
|
13534
13563
|
var IconPaste = () => /* @__PURE__ */ React197.createElement("svg", { ...s }, /* @__PURE__ */ React197.createElement("path", { d: "M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z" }));
|
|
13535
13564
|
|
|
13536
13565
|
// lib/RufousTextEditor/Toolbar.tsx
|
|
13566
|
+
var BASIC_MOBILE_BUTTONS = /* @__PURE__ */ new Set([
|
|
13567
|
+
"undo",
|
|
13568
|
+
"redo",
|
|
13569
|
+
"bold",
|
|
13570
|
+
"italic",
|
|
13571
|
+
"link",
|
|
13572
|
+
"ul",
|
|
13573
|
+
"ol"
|
|
13574
|
+
]);
|
|
13537
13575
|
var COLOR_PALETTE = [
|
|
13538
13576
|
// Row 1: blacks/grays
|
|
13539
13577
|
"#000000",
|
|
@@ -13981,7 +14019,47 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
|
|
|
13981
14019
|
const [todoEnabled, setTodoEnabled] = (0, import_react53.useState)(false);
|
|
13982
14020
|
const ttsRef = (0, import_react53.useRef)(null);
|
|
13983
14021
|
const sttRef = (0, import_react53.useRef)(null);
|
|
13984
|
-
const
|
|
14022
|
+
const [isMobile, setIsMobile] = (0, import_react53.useState)(false);
|
|
14023
|
+
const [expanded, setExpanded] = (0, import_react53.useState)(false);
|
|
14024
|
+
const [overflows, setOverflows] = (0, import_react53.useState)(false);
|
|
14025
|
+
const [winW, setWinW] = (0, import_react53.useState)(typeof window !== "undefined" ? window.innerWidth : 0);
|
|
14026
|
+
const rowRef = (0, import_react53.useRef)(null);
|
|
14027
|
+
(0, import_react53.useEffect)(() => {
|
|
14028
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
14029
|
+
const mq = window.matchMedia("(max-width: 600px)");
|
|
14030
|
+
const update = () => setIsMobile(mq.matches);
|
|
14031
|
+
update();
|
|
14032
|
+
mq.addEventListener("change", update);
|
|
14033
|
+
return () => mq.removeEventListener("change", update);
|
|
14034
|
+
}, []);
|
|
14035
|
+
(0, import_react53.useEffect)(() => {
|
|
14036
|
+
if (typeof window === "undefined") return;
|
|
14037
|
+
const onResize = () => {
|
|
14038
|
+
setWinW(window.innerWidth);
|
|
14039
|
+
setOverflows(false);
|
|
14040
|
+
};
|
|
14041
|
+
window.addEventListener("resize", onResize);
|
|
14042
|
+
return () => window.removeEventListener("resize", onResize);
|
|
14043
|
+
}, []);
|
|
14044
|
+
const hasCollapsibleButtons = !visibleButtons ? true : [...visibleButtons].some((b) => !BASIC_MOBILE_BUTTONS.has(b));
|
|
14045
|
+
const collapsedActive = isMobile && overflows && hasCollapsibleButtons && !expanded;
|
|
14046
|
+
const show = (id) => {
|
|
14047
|
+
if (visibleButtons && !visibleButtons.has(id)) return false;
|
|
14048
|
+
if (collapsedActive && !BASIC_MOBILE_BUTTONS.has(id)) return false;
|
|
14049
|
+
return true;
|
|
14050
|
+
};
|
|
14051
|
+
(0, import_react53.useLayoutEffect)(() => {
|
|
14052
|
+
if (collapsedActive) return;
|
|
14053
|
+
const row = rowRef.current;
|
|
14054
|
+
if (!row) return;
|
|
14055
|
+
const kids = Array.from(row.children).filter(
|
|
14056
|
+
(el) => el.offsetParent !== null && !el.classList?.contains("rte-toolbar-toggle")
|
|
14057
|
+
);
|
|
14058
|
+
const firstTop = kids.length ? kids[0].offsetTop : 0;
|
|
14059
|
+
const wraps = kids.some((el) => el.offsetTop - firstTop > 2);
|
|
14060
|
+
const next = isMobile && wraps;
|
|
14061
|
+
setOverflows((prev) => prev === next ? prev : next);
|
|
14062
|
+
}, [collapsedActive, isMobile, expanded, winW, visibleButtons]);
|
|
13985
14063
|
(0, import_react53.useEffect)(() => {
|
|
13986
14064
|
if (!editor) return;
|
|
13987
14065
|
const onTransaction = () => setEditorState((n) => n + 1);
|
|
@@ -14055,7 +14133,7 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
|
|
|
14055
14133
|
setTimeout(() => setTranslateStatus(""), 2e3);
|
|
14056
14134
|
}, [editor, translateSource, translateTarget, onTranslate]);
|
|
14057
14135
|
if (!editor) return null;
|
|
14058
|
-
return /* @__PURE__ */ import_react53.default.createElement("div", { className: "toolbar" }, /* @__PURE__ */ import_react53.default.createElement("div", { className: `toolbar-row ${onClose ? "with-close" : ""}` }, (show("undo") || show("redo")) && /* @__PURE__ */ import_react53.default.createElement("div", { className: "toolbar-group" }, show("undo") && /* @__PURE__ */ import_react53.default.createElement(Tooltip, { title: "Undo (Ctrl+Z)", placement: "top" }, /* @__PURE__ */ import_react53.default.createElement(
|
|
14136
|
+
return /* @__PURE__ */ import_react53.default.createElement("div", { className: "toolbar" }, /* @__PURE__ */ import_react53.default.createElement("div", { ref: rowRef, className: `toolbar-row ${onClose ? "with-close" : ""}` }, (show("undo") || show("redo")) && /* @__PURE__ */ import_react53.default.createElement("div", { className: "toolbar-group" }, show("undo") && /* @__PURE__ */ import_react53.default.createElement(Tooltip, { title: "Undo (Ctrl+Z)", placement: "top" }, /* @__PURE__ */ import_react53.default.createElement(
|
|
14059
14137
|
"button",
|
|
14060
14138
|
{
|
|
14061
14139
|
className: "toolbar-btn",
|
|
@@ -14570,7 +14648,18 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
|
|
|
14570
14648
|
return true;
|
|
14571
14649
|
}).run();
|
|
14572
14650
|
} }, /* @__PURE__ */ import_react53.default.createElement("span", { className: `task-icon task-${status}` }, /* @__PURE__ */ import_react53.default.createElement("img", { src: images[status], alt: status })), " ", labels[status]);
|
|
14573
|
-
})))
|
|
14651
|
+
}))), isMobile && overflows && hasCollapsibleButtons && /* @__PURE__ */ import_react53.default.createElement(
|
|
14652
|
+
"button",
|
|
14653
|
+
{
|
|
14654
|
+
type: "button",
|
|
14655
|
+
className: `toolbar-btn rte-toolbar-toggle ${expanded ? "is-expanded" : ""}`,
|
|
14656
|
+
onClick: () => setExpanded((v) => !v),
|
|
14657
|
+
title: expanded ? "Show fewer options" : "Show more options",
|
|
14658
|
+
"aria-label": expanded ? "Collapse toolbar" : "Expand toolbar",
|
|
14659
|
+
"aria-expanded": expanded
|
|
14660
|
+
},
|
|
14661
|
+
/* @__PURE__ */ import_react53.default.createElement(ChevronDown, { size: 18 })
|
|
14662
|
+
)), onClose && /* @__PURE__ */ import_react53.default.createElement("div", { className: "toolbar-row-right" }, /* @__PURE__ */ import_react53.default.createElement(Tooltip, { title: "Close", placement: "top" }, /* @__PURE__ */ import_react53.default.createElement(
|
|
14574
14663
|
"button",
|
|
14575
14664
|
{
|
|
14576
14665
|
className: "toolbar-btn btn-cross",
|
package/dist/main.css
CHANGED
|
@@ -8171,6 +8171,25 @@ pre {
|
|
|
8171
8171
|
border-right: none;
|
|
8172
8172
|
margin-right: 0;
|
|
8173
8173
|
}
|
|
8174
|
+
.rf-rte-wrapper .toolbar-group:empty {
|
|
8175
|
+
display: none;
|
|
8176
|
+
}
|
|
8177
|
+
.rf-rte-wrapper .rte-toolbar-toggle {
|
|
8178
|
+
margin-left: auto;
|
|
8179
|
+
color: #a81c08;
|
|
8180
|
+
}
|
|
8181
|
+
.rf-rte-wrapper .toolbar-row.with-close .rte-toolbar-toggle {
|
|
8182
|
+
margin-right: 9px;
|
|
8183
|
+
}
|
|
8184
|
+
.rf-rte-wrapper .toolbar-row.with-close .rte-toolbar-toggle.is-expanded {
|
|
8185
|
+
margin-right: -24px;
|
|
8186
|
+
}
|
|
8187
|
+
.rf-rte-wrapper .rte-toolbar-toggle svg {
|
|
8188
|
+
transition: transform 0.2s ease;
|
|
8189
|
+
}
|
|
8190
|
+
.rf-rte-wrapper .rte-toolbar-toggle.is-expanded svg {
|
|
8191
|
+
transform: rotate(180deg);
|
|
8192
|
+
}
|
|
8174
8193
|
.rf-rte-wrapper .toolbar-btn {
|
|
8175
8194
|
display: inline-flex;
|
|
8176
8195
|
align-items: center;
|
package/dist/main.js
CHANGED
|
@@ -2468,28 +2468,55 @@ var TextField = forwardRef6(({
|
|
|
2468
2468
|
className
|
|
2469
2469
|
].filter(Boolean).join(" ");
|
|
2470
2470
|
const internalRef = React143.useRef(null);
|
|
2471
|
+
const numberMin = type === "number" ? slotProps?.input?.min ?? props.min : void 0;
|
|
2472
|
+
const numberMax = type === "number" ? slotProps?.input?.max ?? props.max : void 0;
|
|
2473
|
+
const setNativeValue = (val) => {
|
|
2474
|
+
if (!internalRef.current) return;
|
|
2475
|
+
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
|
|
2476
|
+
setter?.call(internalRef.current, val);
|
|
2477
|
+
};
|
|
2478
|
+
const emitChange = (e, numericValue) => {
|
|
2479
|
+
const syntheticEvent = Object.assign({}, e, {
|
|
2480
|
+
target: Object.assign({}, e.target, { value: numericValue }),
|
|
2481
|
+
currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
|
|
2482
|
+
});
|
|
2483
|
+
onChange?.(syntheticEvent);
|
|
2484
|
+
};
|
|
2471
2485
|
const handleChange = (e) => {
|
|
2472
2486
|
if (type === "number") {
|
|
2473
|
-
|
|
2474
|
-
const inputMax = slotProps?.input?.max ?? props.max;
|
|
2487
|
+
let raw = e.target.value;
|
|
2475
2488
|
const inputMaxLength = slotProps?.input?.maxLength ?? props.maxLength;
|
|
2476
2489
|
if (inputMaxLength != null) {
|
|
2477
2490
|
const digits = raw.replace(/[^0-9]/g, "");
|
|
2478
2491
|
if (digits.length > Number(inputMaxLength)) return;
|
|
2479
2492
|
}
|
|
2480
|
-
if (
|
|
2481
|
-
|
|
2493
|
+
if (numberMax != null && raw !== "" && Number(raw) > Number(numberMax)) {
|
|
2494
|
+
raw = String(numberMax);
|
|
2495
|
+
setNativeValue(raw);
|
|
2482
2496
|
}
|
|
2483
|
-
|
|
2484
|
-
const syntheticEvent = Object.assign({}, e, {
|
|
2485
|
-
target: Object.assign({}, e.target, { value: numericValue }),
|
|
2486
|
-
currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
|
|
2487
|
-
});
|
|
2488
|
-
onChange?.(syntheticEvent);
|
|
2497
|
+
emitChange(e, raw === "" ? "" : Number(raw));
|
|
2489
2498
|
return;
|
|
2490
2499
|
}
|
|
2491
2500
|
onChange?.(e);
|
|
2492
2501
|
};
|
|
2502
|
+
const handleBlur = (e) => {
|
|
2503
|
+
if (type === "number") {
|
|
2504
|
+
const raw = e.target.value;
|
|
2505
|
+
if (raw !== "") {
|
|
2506
|
+
const n = Number(raw);
|
|
2507
|
+
if (!isNaN(n)) {
|
|
2508
|
+
let clamped = n;
|
|
2509
|
+
if (numberMin != null && clamped < Number(numberMin)) clamped = Number(numberMin);
|
|
2510
|
+
if (numberMax != null && clamped > Number(numberMax)) clamped = Number(numberMax);
|
|
2511
|
+
if (clamped !== n) {
|
|
2512
|
+
setNativeValue(String(clamped));
|
|
2513
|
+
emitChange(e, clamped);
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
onBlur?.(e);
|
|
2519
|
+
};
|
|
2493
2520
|
const triggerChange = () => {
|
|
2494
2521
|
if (internalRef.current) {
|
|
2495
2522
|
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
|
|
@@ -2504,9 +2531,10 @@ var TextField = forwardRef6(({
|
|
|
2504
2531
|
const stepBy = (delta) => {
|
|
2505
2532
|
if (!internalRef.current) return;
|
|
2506
2533
|
const step = Number(stepProp ?? (numberVariant ? STEP_BY_VARIANT[numberVariant] : 1));
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2534
|
+
let newVal = (parseFloat(internalRef.current.value) || 0) + delta * step;
|
|
2535
|
+
if (numberMax != null && newVal > Number(numberMax)) newVal = Number(numberMax);
|
|
2536
|
+
if (numberMin != null && newVal < Number(numberMin)) newVal = Number(numberMin);
|
|
2537
|
+
setNativeValue(String(newVal));
|
|
2510
2538
|
triggerChange();
|
|
2511
2539
|
};
|
|
2512
2540
|
const handleIncrement = (e) => {
|
|
@@ -2578,7 +2606,8 @@ var TextField = forwardRef6(({
|
|
|
2578
2606
|
readOnly,
|
|
2579
2607
|
...slotProps?.input,
|
|
2580
2608
|
...props,
|
|
2581
|
-
onChange: handleChange
|
|
2609
|
+
onChange: handleChange,
|
|
2610
|
+
onBlur: handleBlur
|
|
2582
2611
|
}
|
|
2583
2612
|
), InputProps?.endAdornment && /* @__PURE__ */ React143.createElement("div", { className: "rf-text-field__adornment rf-text-field__adornment--end" }, InputProps.endAdornment), !isTextarea && type === "number" && !disabled && !readOnly && /* @__PURE__ */ React143.createElement("div", { className: "rf-text-field__number-controls" }, /* @__PURE__ */ React143.createElement("button", { type: "button", tabIndex: -1, onClick: handleIncrement, className: "rf-text-field__number-btn" }, /* @__PURE__ */ React143.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ React143.createElement("path", { d: "M4 0L8 5H0L4 0Z" }))), /* @__PURE__ */ React143.createElement("button", { type: "button", tabIndex: -1, onClick: handleDecrement, className: "rf-text-field__number-btn", style: { marginTop: 2 } }, /* @__PURE__ */ React143.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ React143.createElement("path", { d: "M4 5L0 0H8L4 5Z" })))), hasLabel && /* @__PURE__ */ React143.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, " ", required && /* @__PURE__ */ React143.createElement("span", { className: "rf-text-field__asterisk" }, "*")), variant === "outlined" && /* @__PURE__ */ React143.createElement("fieldset", { className: "rf-text-field__notch" }, hasLabel ? /* @__PURE__ */ React143.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React143.createElement("span", null, label, " ", required ? "*" : "")) : /* @__PURE__ */ React143.createElement("legend", { className: "rf-text-field__legend--empty" }))), helperText && /* @__PURE__ */ React143.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
|
|
2584
2613
|
});
|
|
@@ -11898,7 +11927,7 @@ function createMentionSuggestion(users) {
|
|
|
11898
11927
|
}
|
|
11899
11928
|
|
|
11900
11929
|
// lib/RufousTextEditor/Toolbar.tsx
|
|
11901
|
-
import React198, { useState as useState34, useRef as useRef30, useEffect as useEffect27, useCallback as useCallback17 } from "react";
|
|
11930
|
+
import React198, { useState as useState34, useRef as useRef30, useEffect as useEffect27, useLayoutEffect as useLayoutEffect4, useCallback as useCallback17 } from "react";
|
|
11902
11931
|
import { createPortal as createPortal4 } from "react-dom";
|
|
11903
11932
|
|
|
11904
11933
|
// lib/RufousTextEditor/TextToSpeech.tsx
|
|
@@ -13328,6 +13357,15 @@ var IconCheck = () => /* @__PURE__ */ React197.createElement("svg", { ...s }, /*
|
|
|
13328
13357
|
var IconPaste = () => /* @__PURE__ */ React197.createElement("svg", { ...s }, /* @__PURE__ */ React197.createElement("path", { d: "M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z" }));
|
|
13329
13358
|
|
|
13330
13359
|
// lib/RufousTextEditor/Toolbar.tsx
|
|
13360
|
+
var BASIC_MOBILE_BUTTONS = /* @__PURE__ */ new Set([
|
|
13361
|
+
"undo",
|
|
13362
|
+
"redo",
|
|
13363
|
+
"bold",
|
|
13364
|
+
"italic",
|
|
13365
|
+
"link",
|
|
13366
|
+
"ul",
|
|
13367
|
+
"ol"
|
|
13368
|
+
]);
|
|
13331
13369
|
var COLOR_PALETTE = [
|
|
13332
13370
|
// Row 1: blacks/grays
|
|
13333
13371
|
"#000000",
|
|
@@ -13775,7 +13813,47 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
|
|
|
13775
13813
|
const [todoEnabled, setTodoEnabled] = useState34(false);
|
|
13776
13814
|
const ttsRef = useRef30(null);
|
|
13777
13815
|
const sttRef = useRef30(null);
|
|
13778
|
-
const
|
|
13816
|
+
const [isMobile, setIsMobile] = useState34(false);
|
|
13817
|
+
const [expanded, setExpanded] = useState34(false);
|
|
13818
|
+
const [overflows, setOverflows] = useState34(false);
|
|
13819
|
+
const [winW, setWinW] = useState34(typeof window !== "undefined" ? window.innerWidth : 0);
|
|
13820
|
+
const rowRef = useRef30(null);
|
|
13821
|
+
useEffect27(() => {
|
|
13822
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
13823
|
+
const mq = window.matchMedia("(max-width: 600px)");
|
|
13824
|
+
const update = () => setIsMobile(mq.matches);
|
|
13825
|
+
update();
|
|
13826
|
+
mq.addEventListener("change", update);
|
|
13827
|
+
return () => mq.removeEventListener("change", update);
|
|
13828
|
+
}, []);
|
|
13829
|
+
useEffect27(() => {
|
|
13830
|
+
if (typeof window === "undefined") return;
|
|
13831
|
+
const onResize = () => {
|
|
13832
|
+
setWinW(window.innerWidth);
|
|
13833
|
+
setOverflows(false);
|
|
13834
|
+
};
|
|
13835
|
+
window.addEventListener("resize", onResize);
|
|
13836
|
+
return () => window.removeEventListener("resize", onResize);
|
|
13837
|
+
}, []);
|
|
13838
|
+
const hasCollapsibleButtons = !visibleButtons ? true : [...visibleButtons].some((b) => !BASIC_MOBILE_BUTTONS.has(b));
|
|
13839
|
+
const collapsedActive = isMobile && overflows && hasCollapsibleButtons && !expanded;
|
|
13840
|
+
const show = (id) => {
|
|
13841
|
+
if (visibleButtons && !visibleButtons.has(id)) return false;
|
|
13842
|
+
if (collapsedActive && !BASIC_MOBILE_BUTTONS.has(id)) return false;
|
|
13843
|
+
return true;
|
|
13844
|
+
};
|
|
13845
|
+
useLayoutEffect4(() => {
|
|
13846
|
+
if (collapsedActive) return;
|
|
13847
|
+
const row = rowRef.current;
|
|
13848
|
+
if (!row) return;
|
|
13849
|
+
const kids = Array.from(row.children).filter(
|
|
13850
|
+
(el) => el.offsetParent !== null && !el.classList?.contains("rte-toolbar-toggle")
|
|
13851
|
+
);
|
|
13852
|
+
const firstTop = kids.length ? kids[0].offsetTop : 0;
|
|
13853
|
+
const wraps = kids.some((el) => el.offsetTop - firstTop > 2);
|
|
13854
|
+
const next = isMobile && wraps;
|
|
13855
|
+
setOverflows((prev) => prev === next ? prev : next);
|
|
13856
|
+
}, [collapsedActive, isMobile, expanded, winW, visibleButtons]);
|
|
13779
13857
|
useEffect27(() => {
|
|
13780
13858
|
if (!editor) return;
|
|
13781
13859
|
const onTransaction = () => setEditorState((n) => n + 1);
|
|
@@ -13849,7 +13927,7 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
|
|
|
13849
13927
|
setTimeout(() => setTranslateStatus(""), 2e3);
|
|
13850
13928
|
}, [editor, translateSource, translateTarget, onTranslate]);
|
|
13851
13929
|
if (!editor) return null;
|
|
13852
|
-
return /* @__PURE__ */ React198.createElement("div", { className: "toolbar" }, /* @__PURE__ */ React198.createElement("div", { className: `toolbar-row ${onClose ? "with-close" : ""}` }, (show("undo") || show("redo")) && /* @__PURE__ */ React198.createElement("div", { className: "toolbar-group" }, show("undo") && /* @__PURE__ */ React198.createElement(Tooltip, { title: "Undo (Ctrl+Z)", placement: "top" }, /* @__PURE__ */ React198.createElement(
|
|
13930
|
+
return /* @__PURE__ */ React198.createElement("div", { className: "toolbar" }, /* @__PURE__ */ React198.createElement("div", { ref: rowRef, className: `toolbar-row ${onClose ? "with-close" : ""}` }, (show("undo") || show("redo")) && /* @__PURE__ */ React198.createElement("div", { className: "toolbar-group" }, show("undo") && /* @__PURE__ */ React198.createElement(Tooltip, { title: "Undo (Ctrl+Z)", placement: "top" }, /* @__PURE__ */ React198.createElement(
|
|
13853
13931
|
"button",
|
|
13854
13932
|
{
|
|
13855
13933
|
className: "toolbar-btn",
|
|
@@ -14364,7 +14442,18 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
|
|
|
14364
14442
|
return true;
|
|
14365
14443
|
}).run();
|
|
14366
14444
|
} }, /* @__PURE__ */ React198.createElement("span", { className: `task-icon task-${status}` }, /* @__PURE__ */ React198.createElement("img", { src: images[status], alt: status })), " ", labels[status]);
|
|
14367
|
-
})))
|
|
14445
|
+
}))), isMobile && overflows && hasCollapsibleButtons && /* @__PURE__ */ React198.createElement(
|
|
14446
|
+
"button",
|
|
14447
|
+
{
|
|
14448
|
+
type: "button",
|
|
14449
|
+
className: `toolbar-btn rte-toolbar-toggle ${expanded ? "is-expanded" : ""}`,
|
|
14450
|
+
onClick: () => setExpanded((v) => !v),
|
|
14451
|
+
title: expanded ? "Show fewer options" : "Show more options",
|
|
14452
|
+
"aria-label": expanded ? "Collapse toolbar" : "Expand toolbar",
|
|
14453
|
+
"aria-expanded": expanded
|
|
14454
|
+
},
|
|
14455
|
+
/* @__PURE__ */ React198.createElement(ChevronDown, { size: 18 })
|
|
14456
|
+
)), onClose && /* @__PURE__ */ React198.createElement("div", { className: "toolbar-row-right" }, /* @__PURE__ */ React198.createElement(Tooltip, { title: "Close", placement: "top" }, /* @__PURE__ */ React198.createElement(
|
|
14368
14457
|
"button",
|
|
14369
14458
|
{
|
|
14370
14459
|
className: "toolbar-btn btn-cross",
|