@sia.soul/sia-react-ui 0.1.77 → 0.1.78
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/chart.js +2 -3
- package/dist/{chunk-Q4FDV6KP.js → chunk-BDS42FR3.js} +2 -4
- package/dist/{chunk-JNZXYBGM.js → chunk-GODBVCIQ.js} +2 -2
- package/dist/chunk-JZWTTSOZ.js +131 -0
- package/dist/{chunk-QDZXP2UO.js → chunk-NK2FZWKM.js} +8 -10
- package/dist/{chunk-TKCXP6RZ.js → chunk-WXERMWTW.js} +113 -436
- package/dist/{chunk-YMOOL62S.js → chunk-XHLIIDD2.js} +407 -21
- package/dist/{chunk-K5OU5NOT.js → chunk-Y4Y2NVBM.js} +2 -2
- package/dist/{core-CBLT4Vfl.d.ts → core-0ml74Q-C.d.ts} +7 -0
- package/dist/{core-Bx07vzrr.d.cts → core-vGTHkzIa.d.cts} +7 -0
- package/dist/core.cjs +336 -275
- package/dist/core.css +19 -0
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +5 -6
- package/dist/index.cjs +1006 -943
- package/dist/index.css +19 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -15
- package/dist/rich-text-editor.cjs +522 -74
- package/dist/rich-text-editor.js +3 -3
- package/dist/select-date-range.cjs +305 -178
- package/dist/select-date-range.js +4 -4
- package/package.json +1 -1
- package/dist/chunk-IKAMZNCK.js +0 -65
- package/dist/chunk-SMCYEPBL.js +0 -73
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Button
|
|
3
|
-
|
|
2
|
+
Button,
|
|
3
|
+
TextArea
|
|
4
|
+
} from "./chunk-JZWTTSOZ.js";
|
|
4
5
|
import {
|
|
5
6
|
PopupPortal,
|
|
6
7
|
useControlSize,
|
|
@@ -1340,10 +1341,331 @@ var Dropdown = Object.assign(DropdownRoot, {
|
|
|
1340
1341
|
Button: DropdownButton
|
|
1341
1342
|
});
|
|
1342
1343
|
|
|
1344
|
+
// src/components/Modal.tsx
|
|
1345
|
+
import { forwardRef as forwardRef2, useEffect as useEffect4, useId as useId2, useRef as useRef4, useState as useState3 } from "react";
|
|
1346
|
+
import { createRoot } from "react-dom/client";
|
|
1347
|
+
|
|
1348
|
+
// src/components/Overlay.tsx
|
|
1349
|
+
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
1350
|
+
import { createPortal } from "react-dom";
|
|
1351
|
+
var bodyLockCount = 0;
|
|
1352
|
+
var previousBodyOverflow = "";
|
|
1353
|
+
var overlayStack = [];
|
|
1354
|
+
function lockBodyScroll() {
|
|
1355
|
+
if (bodyLockCount === 0) {
|
|
1356
|
+
previousBodyOverflow = document.body.style.overflow;
|
|
1357
|
+
document.body.style.overflow = "hidden";
|
|
1358
|
+
}
|
|
1359
|
+
bodyLockCount += 1;
|
|
1360
|
+
return () => {
|
|
1361
|
+
bodyLockCount = Math.max(0, bodyLockCount - 1);
|
|
1362
|
+
if (bodyLockCount === 0) document.body.style.overflow = previousBodyOverflow;
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
function focusableElements(container) {
|
|
1366
|
+
return [...container.querySelectorAll(
|
|
1367
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
1368
|
+
)].filter((element) => !element.hidden && element.getAttribute("aria-hidden") !== "true");
|
|
1369
|
+
}
|
|
1370
|
+
function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
|
|
1371
|
+
const overlayIdRef = useRef3(/* @__PURE__ */ Symbol("sia-overlay"));
|
|
1372
|
+
const closeRef = useRef3(onRequestClose);
|
|
1373
|
+
closeRef.current = onRequestClose;
|
|
1374
|
+
useEffect3(() => {
|
|
1375
|
+
if (!open || typeof document === "undefined") return void 0;
|
|
1376
|
+
const overlayId = overlayIdRef.current;
|
|
1377
|
+
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
1378
|
+
overlayStack.push(overlayId);
|
|
1379
|
+
const unlockBody = lockBodyScroll();
|
|
1380
|
+
const focusTimer = window.setTimeout(() => {
|
|
1381
|
+
const panel = panelRef.current;
|
|
1382
|
+
if (!panel) return;
|
|
1383
|
+
const [firstFocusable] = focusableElements(panel);
|
|
1384
|
+
(firstFocusable ?? panel).focus({ preventScroll: true });
|
|
1385
|
+
}, 0);
|
|
1386
|
+
function handleKeyDown(event) {
|
|
1387
|
+
if (overlayStack.at(-1) !== overlayId) return;
|
|
1388
|
+
if (event.key === "Escape" && keyboard) {
|
|
1389
|
+
event.preventDefault();
|
|
1390
|
+
closeRef.current();
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
if (event.key !== "Tab" || !panelRef.current) return;
|
|
1394
|
+
const focusable = focusableElements(panelRef.current);
|
|
1395
|
+
if (focusable.length === 0) {
|
|
1396
|
+
event.preventDefault();
|
|
1397
|
+
panelRef.current.focus();
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
const first = focusable[0];
|
|
1401
|
+
const last = focusable.at(-1);
|
|
1402
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
1403
|
+
event.preventDefault();
|
|
1404
|
+
last.focus();
|
|
1405
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
1406
|
+
event.preventDefault();
|
|
1407
|
+
first.focus();
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1411
|
+
return () => {
|
|
1412
|
+
window.clearTimeout(focusTimer);
|
|
1413
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1414
|
+
const index = overlayStack.lastIndexOf(overlayId);
|
|
1415
|
+
if (index >= 0) overlayStack.splice(index, 1);
|
|
1416
|
+
unlockBody();
|
|
1417
|
+
previouslyFocused?.focus({ preventScroll: true });
|
|
1418
|
+
};
|
|
1419
|
+
}, [keyboard, open, panelRef]);
|
|
1420
|
+
}
|
|
1421
|
+
function OverlayPortal({ children, container }) {
|
|
1422
|
+
if (typeof document === "undefined") return null;
|
|
1423
|
+
const target = typeof container === "function" ? container() : container ?? document.body;
|
|
1424
|
+
return createPortal(children, target);
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
// src/components/Modal.tsx
|
|
1428
|
+
import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1429
|
+
var modalHandles = /* @__PURE__ */ new Set();
|
|
1430
|
+
var MODAL_MOTION_DURATION = 220;
|
|
1431
|
+
var typeIcons = {
|
|
1432
|
+
info: /* @__PURE__ */ jsx5(Icon, { name: "info", size: 23 }),
|
|
1433
|
+
success: /* @__PURE__ */ jsx5(Icon, { name: "circle-check", size: 23 }),
|
|
1434
|
+
warning: /* @__PURE__ */ jsx5(Icon, { name: "warning", size: 23 }),
|
|
1435
|
+
error: /* @__PURE__ */ jsx5(Icon, { name: "circle-close", size: 23 }),
|
|
1436
|
+
confirm: /* @__PURE__ */ jsx5(Icon, { name: "question", size: 23 })
|
|
1437
|
+
};
|
|
1438
|
+
var ModalRoot = forwardRef2(function Modal({
|
|
1439
|
+
open,
|
|
1440
|
+
title,
|
|
1441
|
+
children,
|
|
1442
|
+
footer,
|
|
1443
|
+
footerExtra,
|
|
1444
|
+
type = "default",
|
|
1445
|
+
okText = "\u786E\u5B9A",
|
|
1446
|
+
cancelText = "\u53D6\u6D88",
|
|
1447
|
+
showCancel = type === "default" || type === "confirm",
|
|
1448
|
+
confirmLoading = false,
|
|
1449
|
+
okButtonProps,
|
|
1450
|
+
cancelButtonProps,
|
|
1451
|
+
closable = true,
|
|
1452
|
+
maskClosable = true,
|
|
1453
|
+
keyboard = true,
|
|
1454
|
+
centered = false,
|
|
1455
|
+
width = 520,
|
|
1456
|
+
height,
|
|
1457
|
+
zIndex = 1e3,
|
|
1458
|
+
getContainer,
|
|
1459
|
+
onOk,
|
|
1460
|
+
onCancel,
|
|
1461
|
+
onOpenChange,
|
|
1462
|
+
afterOpenChange,
|
|
1463
|
+
className = "",
|
|
1464
|
+
style,
|
|
1465
|
+
...props
|
|
1466
|
+
}, forwardedRef) {
|
|
1467
|
+
const localRef = useRef4(null);
|
|
1468
|
+
const titleId = useId2();
|
|
1469
|
+
const [submitting, setSubmitting] = useState3(false);
|
|
1470
|
+
const [rendered, setRendered] = useState3(open);
|
|
1471
|
+
const [closing, setClosing] = useState3(false);
|
|
1472
|
+
const afterOpenChangeRef = useRef4(afterOpenChange);
|
|
1473
|
+
afterOpenChangeRef.current = afterOpenChange;
|
|
1474
|
+
const submitLock = useRef4(false);
|
|
1475
|
+
useEffect4(() => {
|
|
1476
|
+
if (!open || !rendered) return void 0;
|
|
1477
|
+
const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
|
|
1478
|
+
return () => window.clearTimeout(timer);
|
|
1479
|
+
}, [open, rendered]);
|
|
1480
|
+
useEffect4(() => {
|
|
1481
|
+
if (open) {
|
|
1482
|
+
setRendered(true);
|
|
1483
|
+
setClosing(false);
|
|
1484
|
+
return void 0;
|
|
1485
|
+
}
|
|
1486
|
+
if (!rendered) return void 0;
|
|
1487
|
+
setClosing(true);
|
|
1488
|
+
const timer = window.setTimeout(() => {
|
|
1489
|
+
setRendered(false);
|
|
1490
|
+
setClosing(false);
|
|
1491
|
+
afterOpenChangeRef.current?.(false);
|
|
1492
|
+
}, MODAL_MOTION_DURATION);
|
|
1493
|
+
return () => window.clearTimeout(timer);
|
|
1494
|
+
}, [open, rendered]);
|
|
1495
|
+
function setRef(node) {
|
|
1496
|
+
localRef.current = node;
|
|
1497
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
1498
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
1499
|
+
}
|
|
1500
|
+
function requestClose() {
|
|
1501
|
+
if (submitting || confirmLoading) return;
|
|
1502
|
+
onCancel?.();
|
|
1503
|
+
onOpenChange?.(false);
|
|
1504
|
+
}
|
|
1505
|
+
async function handleOk() {
|
|
1506
|
+
if (submitLock.current || confirmLoading) return;
|
|
1507
|
+
submitLock.current = true;
|
|
1508
|
+
if (!onOk) {
|
|
1509
|
+
onOpenChange?.(false);
|
|
1510
|
+
submitLock.current = false;
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
try {
|
|
1514
|
+
const result = onOk();
|
|
1515
|
+
if (result instanceof Promise) {
|
|
1516
|
+
setSubmitting(true);
|
|
1517
|
+
const resolved = await result;
|
|
1518
|
+
if (resolved !== false) onOpenChange?.(false);
|
|
1519
|
+
} else if (result !== false) {
|
|
1520
|
+
onOpenChange?.(false);
|
|
1521
|
+
}
|
|
1522
|
+
} catch {
|
|
1523
|
+
return;
|
|
1524
|
+
} finally {
|
|
1525
|
+
submitLock.current = false;
|
|
1526
|
+
setSubmitting(false);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
|
|
1530
|
+
if (!rendered) return null;
|
|
1531
|
+
const mergedStyle = {
|
|
1532
|
+
...height !== void 0 ? { display: "flex", flexDirection: "column", height, maxHeight: "calc(100dvh - 48px)" } : {},
|
|
1533
|
+
...style,
|
|
1534
|
+
"--sia-modal-width": typeof width === "number" ? `${width}px` : width
|
|
1535
|
+
};
|
|
1536
|
+
const loading = submitting || confirmLoading;
|
|
1537
|
+
const defaultFooter = /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1538
|
+
showCancel ? /* @__PURE__ */ jsx5(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
|
|
1539
|
+
/* @__PURE__ */ jsx5(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
|
|
1540
|
+
] });
|
|
1541
|
+
return /* @__PURE__ */ jsx5(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ jsx5(
|
|
1542
|
+
"div",
|
|
1543
|
+
{
|
|
1544
|
+
className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
|
|
1545
|
+
"data-state": closing ? "closing" : "open",
|
|
1546
|
+
style: { zIndex },
|
|
1547
|
+
onMouseDown: (event) => {
|
|
1548
|
+
if (event.target === event.currentTarget && maskClosable) requestClose();
|
|
1549
|
+
},
|
|
1550
|
+
children: /* @__PURE__ */ jsxs5(
|
|
1551
|
+
"div",
|
|
1552
|
+
{
|
|
1553
|
+
ref: setRef,
|
|
1554
|
+
className: `sia-modal sia-modal--${type} ${className}`.trim(),
|
|
1555
|
+
style: mergedStyle,
|
|
1556
|
+
role: "dialog",
|
|
1557
|
+
"aria-modal": "true",
|
|
1558
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
1559
|
+
tabIndex: -1,
|
|
1560
|
+
...withTitleTooltip(props),
|
|
1561
|
+
children: [
|
|
1562
|
+
/* @__PURE__ */ jsxs5("div", { className: "sia-modal__header", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
1563
|
+
/* @__PURE__ */ jsxs5("div", { className: "sia-modal__heading", children: [
|
|
1564
|
+
typeIcons[type] ? /* @__PURE__ */ jsx5("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
|
|
1565
|
+
title ? /* @__PURE__ */ jsx5("strong", { id: titleId, children: title }) : null
|
|
1566
|
+
] }),
|
|
1567
|
+
closable ? /* @__PURE__ */ jsx5("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ jsx5(Icon, { name: "close", size: 17 }) }) : null
|
|
1568
|
+
] }),
|
|
1569
|
+
children !== void 0 ? /* @__PURE__ */ jsx5("div", { className: "sia-modal__body", style: height !== void 0 ? { flex: 1, minHeight: 0, overflow: "auto" } : void 0, children }) : null,
|
|
1570
|
+
footer !== null ? /* @__PURE__ */ jsxs5("div", { className: "sia-modal__footer", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
1571
|
+
footer === void 0 && footerExtra != null ? /* @__PURE__ */ jsx5("div", { style: { marginRight: "auto" }, children: footerExtra }) : null,
|
|
1572
|
+
footer ?? defaultFooter
|
|
1573
|
+
] }) : null
|
|
1574
|
+
]
|
|
1575
|
+
}
|
|
1576
|
+
)
|
|
1577
|
+
}
|
|
1578
|
+
) });
|
|
1579
|
+
});
|
|
1580
|
+
function openModal(config) {
|
|
1581
|
+
if (typeof document === "undefined") return { destroy() {
|
|
1582
|
+
}, update() {
|
|
1583
|
+
} };
|
|
1584
|
+
const container = document.createElement("div");
|
|
1585
|
+
container.className = "sia-modal-api-host";
|
|
1586
|
+
document.body.appendChild(container);
|
|
1587
|
+
const root = createRoot(container);
|
|
1588
|
+
let currentConfig = config;
|
|
1589
|
+
let currentOpen = true;
|
|
1590
|
+
let destroyed = false;
|
|
1591
|
+
let mounted = false;
|
|
1592
|
+
function cleanup() {
|
|
1593
|
+
if (destroyed) return;
|
|
1594
|
+
destroyed = true;
|
|
1595
|
+
root.unmount();
|
|
1596
|
+
container.remove();
|
|
1597
|
+
modalHandles.delete(handle);
|
|
1598
|
+
}
|
|
1599
|
+
function closeWithMotion() {
|
|
1600
|
+
if (destroyed || !currentOpen) return;
|
|
1601
|
+
currentOpen = false;
|
|
1602
|
+
render();
|
|
1603
|
+
}
|
|
1604
|
+
function ModalInstance() {
|
|
1605
|
+
useEffect4(() => {
|
|
1606
|
+
mounted = true;
|
|
1607
|
+
if (!currentOpen) render();
|
|
1608
|
+
}, []);
|
|
1609
|
+
return /* @__PURE__ */ jsx5(ModalRoot, { ...currentConfig, open: !mounted || currentOpen, onOpenChange: (nextOpen) => {
|
|
1610
|
+
currentConfig.onOpenChange?.(nextOpen);
|
|
1611
|
+
if (!nextOpen) closeWithMotion();
|
|
1612
|
+
}, afterOpenChange: (nextOpen) => {
|
|
1613
|
+
try {
|
|
1614
|
+
currentConfig.afterOpenChange?.(nextOpen);
|
|
1615
|
+
} finally {
|
|
1616
|
+
if (!nextOpen) queueMicrotask(cleanup);
|
|
1617
|
+
}
|
|
1618
|
+
} });
|
|
1619
|
+
}
|
|
1620
|
+
function render() {
|
|
1621
|
+
root.render(/* @__PURE__ */ jsx5(ModalInstance, {}));
|
|
1622
|
+
}
|
|
1623
|
+
const handle = {
|
|
1624
|
+
destroy: closeWithMotion,
|
|
1625
|
+
update(next) {
|
|
1626
|
+
if (destroyed) return;
|
|
1627
|
+
currentConfig = { ...currentConfig, ...next };
|
|
1628
|
+
render();
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
modalHandles.add(handle);
|
|
1632
|
+
render();
|
|
1633
|
+
return handle;
|
|
1634
|
+
}
|
|
1635
|
+
function preset(type, defaults = {}) {
|
|
1636
|
+
return (config) => openModal({
|
|
1637
|
+
okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
|
|
1638
|
+
showCancel: type === "confirm",
|
|
1639
|
+
closable: type !== "confirm",
|
|
1640
|
+
maskClosable: type !== "confirm",
|
|
1641
|
+
...defaults,
|
|
1642
|
+
...config,
|
|
1643
|
+
type
|
|
1644
|
+
});
|
|
1645
|
+
}
|
|
1646
|
+
var Modal2 = Object.assign(ModalRoot, {
|
|
1647
|
+
/** 直接打开实例,返回更新和关闭句柄;关闭动画完成后先调用 afterOpenChange(false),再卸载实例。 */
|
|
1648
|
+
open: openModal,
|
|
1649
|
+
/** 显示普通信息提示。 */
|
|
1650
|
+
info: preset("info", { title: "\u63D0\u793A" }),
|
|
1651
|
+
/** 显示成功提示。 */
|
|
1652
|
+
success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
|
|
1653
|
+
/** 显示警告提示。 */
|
|
1654
|
+
warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
|
|
1655
|
+
/** 显示错误提示。 */
|
|
1656
|
+
error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
|
|
1657
|
+
/** 打开确认弹框,支持异步确认;返回 false 可阻止关闭。 */
|
|
1658
|
+
confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
|
|
1659
|
+
/** 关闭由此 API 打开的所有弹层。 */
|
|
1660
|
+
destroyAll() {
|
|
1661
|
+
[...modalHandles].forEach((handle) => handle.destroy());
|
|
1662
|
+
}
|
|
1663
|
+
});
|
|
1664
|
+
|
|
1343
1665
|
// src/components/Input.tsx
|
|
1344
|
-
import { forwardRef as
|
|
1345
|
-
import { jsx as
|
|
1346
|
-
var Input =
|
|
1666
|
+
import { forwardRef as forwardRef3, useId as useId3, useRef as useRef5, useState as useState4 } from "react";
|
|
1667
|
+
import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1668
|
+
var Input = forwardRef3(function Input2({
|
|
1347
1669
|
label,
|
|
1348
1670
|
hint,
|
|
1349
1671
|
status = "default",
|
|
@@ -1362,15 +1684,18 @@ var Input = forwardRef2(function Input2({
|
|
|
1362
1684
|
defaultValue,
|
|
1363
1685
|
maxLength,
|
|
1364
1686
|
onChange,
|
|
1687
|
+
expandable = false,
|
|
1365
1688
|
...props
|
|
1366
1689
|
}, forwardedRef) {
|
|
1367
1690
|
const size = useControlSize(sizeProp);
|
|
1368
|
-
const fallbackId =
|
|
1691
|
+
const fallbackId = useId3();
|
|
1369
1692
|
const inputId = id ?? fallbackId;
|
|
1370
|
-
const localRef =
|
|
1371
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
1693
|
+
const localRef = useRef5(null);
|
|
1694
|
+
const [uncontrolledValue, setUncontrolledValue] = useState4(() => defaultValue === void 0 ? "" : String(defaultValue));
|
|
1372
1695
|
const currentText = value !== void 0 ? String(value) : uncontrolledValue;
|
|
1373
1696
|
const hasValue = currentText.length > 0;
|
|
1697
|
+
const [expanded, setExpanded] = useState4(false);
|
|
1698
|
+
const [expandedDraft, setExpandedDraft] = useState4("");
|
|
1374
1699
|
const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
|
|
1375
1700
|
const hintId = `${inputId}-hint`;
|
|
1376
1701
|
const describedBy = [props["aria-describedby"], hint ? hintId : null].filter(Boolean).join(" ") || void 0;
|
|
@@ -1406,7 +1731,7 @@ var Input = forwardRef2(function Input2({
|
|
|
1406
1731
|
event.preventDefault();
|
|
1407
1732
|
localRef.current?.focus({ preventScroll: true });
|
|
1408
1733
|
}
|
|
1409
|
-
const input = /* @__PURE__ */
|
|
1734
|
+
const input = /* @__PURE__ */ jsx6(
|
|
1410
1735
|
"input",
|
|
1411
1736
|
{
|
|
1412
1737
|
...withTitleTooltip(props),
|
|
@@ -1423,24 +1748,82 @@ var Input = forwardRef2(function Input2({
|
|
|
1423
1748
|
onChange: handleChange
|
|
1424
1749
|
}
|
|
1425
1750
|
);
|
|
1426
|
-
const control = /* @__PURE__ */
|
|
1427
|
-
prefix ? /* @__PURE__ */
|
|
1428
|
-
floatingPlaceholder ? /* @__PURE__ */
|
|
1751
|
+
const control = /* @__PURE__ */ jsxs6("span", { onMouseDown: handleControlMouseDown, className: `sia-input-control sia-input-control--${size} sia-input-control--${status}${floatingPlaceholder ? " sia-input-control--floating" : ""}${floatingPlaceholder && hasValue ? " is-filled" : ""}${disabled ? " is-disabled" : ""}`, children: [
|
|
1752
|
+
prefix ? /* @__PURE__ */ jsx6("span", { className: "sia-input-control__affix", children: prefix }) : null,
|
|
1753
|
+
floatingPlaceholder ? /* @__PURE__ */ jsxs6("span", { className: "sia-input-control__input-wrap", children: [
|
|
1429
1754
|
input,
|
|
1430
|
-
/* @__PURE__ */
|
|
1755
|
+
/* @__PURE__ */ jsx6("span", { className: "sia-input-control__floating-placeholder", "aria-hidden": "true", children: placeholder })
|
|
1431
1756
|
] }) : input,
|
|
1432
|
-
allowClear && hasValue && !disabled ? /* @__PURE__ */
|
|
1433
|
-
suffix ? /* @__PURE__ */
|
|
1434
|
-
|
|
1757
|
+
allowClear && hasValue && !disabled ? /* @__PURE__ */ jsx6("button", { className: "sia-input-control__clear", type: "button", "aria-label": "\u6E05\u7A7A\u8F93\u5165", onClick: clearValue, children: /* @__PURE__ */ jsx6(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
|
|
1758
|
+
suffix ? /* @__PURE__ */ jsx6("span", { className: "sia-input-control__affix", children: suffix }) : null,
|
|
1759
|
+
expandable && !disabled && !props.readOnly && (!props.type || props.type === "text") ? /* @__PURE__ */ jsx6(
|
|
1760
|
+
"button",
|
|
1761
|
+
{
|
|
1762
|
+
type: "button",
|
|
1763
|
+
className: "sia-input-control__expand",
|
|
1764
|
+
"aria-label": "\u5C55\u5F00\u7F16\u8F91",
|
|
1765
|
+
title: "\u5C55\u5F00\u7F16\u8F91",
|
|
1766
|
+
onClick: () => {
|
|
1767
|
+
if (localRef.current?.matches(":disabled")) return;
|
|
1768
|
+
setExpandedDraft(currentText);
|
|
1769
|
+
setExpanded(true);
|
|
1770
|
+
},
|
|
1771
|
+
children: /* @__PURE__ */ jsx6(Icon, { name: "expand", size: 15 })
|
|
1772
|
+
}
|
|
1773
|
+
) : null,
|
|
1774
|
+
showCount ? /* @__PURE__ */ jsxs6("span", { className: `sia-input-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
|
|
1435
1775
|
currentText.length,
|
|
1436
1776
|
maxLength !== void 0 ? `/${maxLength}` : null
|
|
1437
1777
|
] }) : null
|
|
1438
1778
|
] });
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1779
|
+
const editor = expandable ? /* @__PURE__ */ jsx6(
|
|
1780
|
+
Modal2,
|
|
1781
|
+
{
|
|
1782
|
+
open: expanded,
|
|
1783
|
+
title: "\u5C55\u5F00\u7F16\u8F91",
|
|
1784
|
+
okText: "\u786E\u5B9A",
|
|
1785
|
+
cancelText: "\u53D6\u6D88",
|
|
1786
|
+
onCancel: () => setExpanded(false),
|
|
1787
|
+
afterOpenChange: (open) => {
|
|
1788
|
+
if (!open) setExpandedDraft("");
|
|
1789
|
+
},
|
|
1790
|
+
onOk: () => {
|
|
1791
|
+
const target = localRef.current;
|
|
1792
|
+
if (!target || target.matches(":disabled") || props.readOnly) return false;
|
|
1793
|
+
const normalized = expandedDraft.replace(/\r\n|[\r\n]/g, " ");
|
|
1794
|
+
const next = maxLength !== void 0 && maxLength >= 0 ? normalized.slice(0, maxLength) : normalized;
|
|
1795
|
+
Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set?.call(target, next);
|
|
1796
|
+
target.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1797
|
+
setUncontrolledValue(next);
|
|
1798
|
+
setExpanded(false);
|
|
1799
|
+
},
|
|
1800
|
+
children: /* @__PURE__ */ jsx6(
|
|
1801
|
+
TextArea,
|
|
1802
|
+
{
|
|
1803
|
+
"aria-label": "\u5C55\u5F00\u7F16\u8F91\u5185\u5BB9",
|
|
1804
|
+
value: expandedDraft,
|
|
1805
|
+
onChange: (event) => setExpandedDraft(event.target.value),
|
|
1806
|
+
maxLength,
|
|
1807
|
+
showCount,
|
|
1808
|
+
placeholder,
|
|
1809
|
+
rows: 8,
|
|
1810
|
+
disabled,
|
|
1811
|
+
readOnly: props.readOnly
|
|
1812
|
+
}
|
|
1813
|
+
)
|
|
1814
|
+
}
|
|
1815
|
+
) : null;
|
|
1816
|
+
if (!label && !hint) return /* @__PURE__ */ jsxs6(Fragment5, { children: [
|
|
1817
|
+
/* @__PURE__ */ jsx6("span", { className: `sia-field ${className}`.trim(), children: control }),
|
|
1818
|
+
editor
|
|
1819
|
+
] });
|
|
1820
|
+
return /* @__PURE__ */ jsxs6(Fragment5, { children: [
|
|
1821
|
+
/* @__PURE__ */ jsxs6("span", { className: `sia-field ${className}`.trim(), children: [
|
|
1822
|
+
label ? /* @__PURE__ */ jsx6("label", { className: "sia-field__label", htmlFor: inputId, children: label }) : null,
|
|
1823
|
+
control,
|
|
1824
|
+
hint ? /* @__PURE__ */ jsx6("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
|
|
1825
|
+
] }),
|
|
1826
|
+
editor
|
|
1444
1827
|
] });
|
|
1445
1828
|
});
|
|
1446
1829
|
|
|
@@ -1452,5 +1835,8 @@ export {
|
|
|
1452
1835
|
Steps,
|
|
1453
1836
|
Segmented,
|
|
1454
1837
|
Dropdown,
|
|
1838
|
+
useOverlayLifecycle,
|
|
1839
|
+
OverlayPortal,
|
|
1840
|
+
Modal2 as Modal,
|
|
1455
1841
|
Input
|
|
1456
1842
|
};
|
|
@@ -1887,6 +1887,13 @@ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "prefix
|
|
|
1887
1887
|
showCount?: boolean;
|
|
1888
1888
|
/** 占位文案的显示模式 */
|
|
1889
1889
|
placeholderMode?: InputPlaceholderMode;
|
|
1890
|
+
/**
|
|
1891
|
+
* 在普通文本输入框末尾显示展开按钮,弹框正文仅显示多行编辑器,继承 maxLength、placeholder 和 showCount。
|
|
1892
|
+
* 打开时复制当前值,确定后通过原生 input 事件触发 onChange;受控模式需由调用方回写 value,取消不修改原值。
|
|
1893
|
+
* 多行换行在回填单行输入框时转换为空格;禁用、只读及非 text 类型不显示展开按钮。
|
|
1894
|
+
* @defaultValue false
|
|
1895
|
+
*/
|
|
1896
|
+
expandable?: boolean;
|
|
1890
1897
|
}
|
|
1891
1898
|
/** 输入框组件。 */
|
|
1892
1899
|
declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
|
|
@@ -1887,6 +1887,13 @@ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "prefix
|
|
|
1887
1887
|
showCount?: boolean;
|
|
1888
1888
|
/** 占位文案的显示模式 */
|
|
1889
1889
|
placeholderMode?: InputPlaceholderMode;
|
|
1890
|
+
/**
|
|
1891
|
+
* 在普通文本输入框末尾显示展开按钮,弹框正文仅显示多行编辑器,继承 maxLength、placeholder 和 showCount。
|
|
1892
|
+
* 打开时复制当前值,确定后通过原生 input 事件触发 onChange;受控模式需由调用方回写 value,取消不修改原值。
|
|
1893
|
+
* 多行换行在回填单行输入框时转换为空格;禁用、只读及非 text 类型不显示展开按钮。
|
|
1894
|
+
* @defaultValue false
|
|
1895
|
+
*/
|
|
1896
|
+
expandable?: boolean;
|
|
1890
1897
|
}
|
|
1891
1898
|
/** 输入框组件。 */
|
|
1892
1899
|
declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
|