@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.
@@ -1,6 +1,7 @@
1
1
  import {
2
- Button
3
- } from "./chunk-IKAMZNCK.js";
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 forwardRef2, useId as useId2, useRef as useRef3, useState as useState3 } from "react";
1345
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1346
- var Input = forwardRef2(function Input2({
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 = useId2();
1691
+ const fallbackId = useId3();
1369
1692
  const inputId = id ?? fallbackId;
1370
- const localRef = useRef3(null);
1371
- const [uncontrolledValue, setUncontrolledValue] = useState3(() => defaultValue === void 0 ? "" : String(defaultValue));
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__ */ jsx5(
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__ */ jsxs5("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: [
1427
- prefix ? /* @__PURE__ */ jsx5("span", { className: "sia-input-control__affix", children: prefix }) : null,
1428
- floatingPlaceholder ? /* @__PURE__ */ jsxs5("span", { className: "sia-input-control__input-wrap", children: [
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__ */ jsx5("span", { className: "sia-input-control__floating-placeholder", "aria-hidden": "true", children: placeholder })
1755
+ /* @__PURE__ */ jsx6("span", { className: "sia-input-control__floating-placeholder", "aria-hidden": "true", children: placeholder })
1431
1756
  ] }) : input,
1432
- allowClear && hasValue && !disabled ? /* @__PURE__ */ jsx5("button", { className: "sia-input-control__clear", type: "button", "aria-label": "\u6E05\u7A7A\u8F93\u5165", onClick: clearValue, children: /* @__PURE__ */ jsx5(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
1433
- suffix ? /* @__PURE__ */ jsx5("span", { className: "sia-input-control__affix", children: suffix }) : null,
1434
- showCount ? /* @__PURE__ */ jsxs5("span", { className: `sia-input-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
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
- if (!label && !hint) return /* @__PURE__ */ jsx5("span", { className: `sia-field ${className}`.trim(), children: control });
1440
- return /* @__PURE__ */ jsxs5("span", { className: `sia-field ${className}`.trim(), children: [
1441
- label ? /* @__PURE__ */ jsx5("label", { className: "sia-field__label", htmlFor: inputId, children: label }) : null,
1442
- control,
1443
- hint ? /* @__PURE__ */ jsx5("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
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
  };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  FloatingScrollbarProvider,
3
3
  Select
4
- } from "./chunk-TKCXP6RZ.js";
4
+ } from "./chunk-WXERMWTW.js";
5
5
  import {
6
6
  Icon
7
- } from "./chunk-YMOOL62S.js";
7
+ } from "./chunk-XHLIIDD2.js";
8
8
  import {
9
9
  PopupPortal,
10
10
  useControlSize,
@@ -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>>;