@sia.soul/sia-react-ui 0.1.42 → 0.1.44

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.
@@ -5,7 +5,7 @@ import {
5
5
  Popover,
6
6
  Tooltip,
7
7
  useOverlayLifecycle
8
- } from "./chunk-3Q3S6CDZ.js";
8
+ } from "./chunk-NYJSSPIX.js";
9
9
  import {
10
10
  Dropdown,
11
11
  Icon
@@ -95,6 +95,12 @@ function Card({
95
95
  title,
96
96
  description,
97
97
  extra,
98
+ selectable = false,
99
+ selected,
100
+ defaultSelected = false,
101
+ disabled = false,
102
+ onSelectedChange,
103
+ hoverActions,
98
104
  accent,
99
105
  accentColor,
100
106
  collapsible = false,
@@ -107,9 +113,19 @@ function Card({
107
113
  className = "",
108
114
  style,
109
115
  children,
116
+ onClick,
117
+ onKeyDown,
110
118
  ...props
111
119
  }) {
112
120
  const [internalCollapsed, setInternalCollapsed] = useState2(defaultCollapsed);
121
+ const [internalSelected, setInternalSelected] = useState2(defaultSelected);
122
+ const isSelected = selected ?? internalSelected;
123
+ function toggleSelected() {
124
+ if (!selectable || disabled) return;
125
+ const next = !isSelected;
126
+ if (selected === void 0) setInternalSelected(next);
127
+ onSelectedChange?.(next);
128
+ }
113
129
  const isCollapsed = collapsed ?? internalCollapsed;
114
130
  const hasHeader = title || extra || collapsible;
115
131
  const mergedStyle = accentColor ? { "--sia-card-accent": accentColor, ...style } : style;
@@ -123,19 +139,46 @@ function Card({
123
139
  accent || accentColor ? /* @__PURE__ */ jsx2("span", { className: `sia-card__accent${accent ? ` sia-card__accent--${accent}` : ""}`, "aria-hidden": "true" }) : null,
124
140
  title ? /* @__PURE__ */ jsx2("h3", { className: "sia-card__title", children: title }) : null
125
141
  ] });
126
- return /* @__PURE__ */ jsxs2("section", { className: `sia-card${isCollapsed ? " sia-card--collapsed" : ""} ${className}`.trim(), style: mergedStyle, ...withTitleTooltip(props), children: [
127
- hasHeader ? /* @__PURE__ */ jsxs2("header", { className: "sia-card__header", children: [
128
- collapsible ? /* @__PURE__ */ jsxs2("button", { type: "button", className: "sia-card__collapse-trigger", "aria-expanded": !isCollapsed, onClick: toggleCollapsed, children: [
129
- heading,
130
- /* @__PURE__ */ jsx2(Icon, { name: isCollapsed ? "chevron-down" : "chevron-up", size: 16 })
131
- ] }) : heading,
132
- extra ? /* @__PURE__ */ jsx2("div", { className: "sia-card__extra", children: extra }) : null
133
- ] }) : null,
134
- !isCollapsed ? /* @__PURE__ */ jsxs2(Fragment, { children: [
135
- description ? /* @__PURE__ */ jsx2("p", { className: "sia-card__description", children: description }) : null,
136
- /* @__PURE__ */ jsx2("div", { className: `sia-card__body ${bodyClassName}`.trim(), style: mergedBodyStyle, children })
137
- ] }) : null
138
- ] });
142
+ return /* @__PURE__ */ jsxs2(
143
+ "section",
144
+ {
145
+ className: `sia-card${isCollapsed ? " sia-card--collapsed" : ""}${selectable ? " sia-card--selectable" : ""}${selectable && isSelected ? " sia-card--selected" : ""}${hoverActions ? " sia-card--hover-actions" : ""} ${className}`.trim(),
146
+ style: mergedStyle,
147
+ role: selectable ? "checkbox" : void 0,
148
+ "aria-checked": selectable ? isSelected : void 0,
149
+ "aria-disabled": selectable ? disabled : void 0,
150
+ tabIndex: selectable && !disabled ? 0 : void 0,
151
+ ...withTitleTooltip(props),
152
+ onClick: (event) => {
153
+ onClick?.(event);
154
+ const target = event.target;
155
+ const interactive = target.closest('button, a, input, select, textarea, label, [role="button"], [role="checkbox"], [role="radio"], [role="switch"], [contenteditable="true"], [tabindex]');
156
+ if (!event.defaultPrevented && (!interactive || interactive === event.currentTarget)) toggleSelected();
157
+ },
158
+ onKeyDown: (event) => {
159
+ onKeyDown?.(event);
160
+ if (!event.defaultPrevented && event.target === event.currentTarget && selectable && (event.key === "Enter" || event.key === " ")) {
161
+ event.preventDefault();
162
+ toggleSelected();
163
+ }
164
+ },
165
+ children: [
166
+ selectable && isSelected ? /* @__PURE__ */ jsx2("span", { className: "sia-card__selected-corner", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(Icon, { name: "check", size: 16 }) }) : null,
167
+ hasHeader ? /* @__PURE__ */ jsxs2("header", { className: "sia-card__header", children: [
168
+ collapsible ? /* @__PURE__ */ jsxs2("button", { type: "button", className: "sia-card__collapse-trigger", "aria-expanded": !isCollapsed, onClick: toggleCollapsed, children: [
169
+ heading,
170
+ /* @__PURE__ */ jsx2(Icon, { name: isCollapsed ? "chevron-down" : "chevron-up", size: 16 })
171
+ ] }) : heading,
172
+ extra ? /* @__PURE__ */ jsx2("div", { className: "sia-card__extra", children: extra }) : null
173
+ ] }) : null,
174
+ !isCollapsed ? /* @__PURE__ */ jsxs2(Fragment, { children: [
175
+ description ? /* @__PURE__ */ jsx2("p", { className: "sia-card__description", children: description }) : null,
176
+ /* @__PURE__ */ jsx2("div", { className: `sia-card__body ${bodyClassName}`.trim(), style: mergedBodyStyle, children }),
177
+ hoverActions ? /* @__PURE__ */ jsx2("div", { className: "sia-card__hover-actions", onClick: (event) => event.stopPropagation(), children: hoverActions }) : null
178
+ ] }) : null
179
+ ]
180
+ }
181
+ );
139
182
  }
140
183
 
141
184
  // src/components/Tag.tsx
@@ -1772,13 +1815,13 @@ function TypographyContent({
1772
1815
  useEffect5(() => () => clearTimeout(timer.current), []);
1773
1816
  useLayoutEffect3(() => {
1774
1817
  const element = contentRef.current;
1775
- if (!element || !ellipsis || editing || expanded) return;
1818
+ if (!element || !ellipsis || !expandable || editing || expanded) return;
1776
1819
  const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
1777
1820
  measure();
1778
1821
  const observer = new ResizeObserver(measure);
1779
1822
  observer.observe(element);
1780
1823
  return () => observer.disconnect();
1781
- }, [content, ellipsis, rows, editing, expanded]);
1824
+ }, [content, ellipsis, rows, expandable, editing, expanded]);
1782
1825
  async function copy() {
1783
1826
  try {
1784
1827
  const text = typeof copyable === "object" ? copyable.text ?? contentRef.current?.textContent ?? "" : contentRef.current?.textContent ?? "";
@@ -1294,7 +1294,17 @@ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
1294
1294
  };
1295
1295
  const scanTargets = () => {
1296
1296
  scanFrame = 0;
1297
- const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
1297
+ const managedSelector = ".sia-table__viewport, [data-sia-native-scrollbar], .sia-scrollbar-track, .sia-floating-scrollbar-layer";
1298
+ const discovered = [];
1299
+ if (!targetRef) {
1300
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
1301
+ acceptNode: (node) => node.matches(managedSelector) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT
1302
+ });
1303
+ for (let node = walker.nextNode(); node; node = walker.nextNode()) {
1304
+ if (node instanceof HTMLElement) discovered.push(node);
1305
+ }
1306
+ }
1307
+ const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...discovered]).filter((target) => target instanceof HTMLElement);
1298
1308
  const nextTargets = /* @__PURE__ */ new Set();
1299
1309
  candidates.forEach((target) => {
1300
1310
  if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
@@ -1312,9 +1322,12 @@ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
1312
1322
  scanFrame = window.requestAnimationFrame(scanTargets);
1313
1323
  };
1314
1324
  const mutationObserver = new MutationObserver((mutations) => {
1315
- if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
1325
+ if (mutations.some((mutation) => {
1326
+ const target = mutation.target instanceof Element ? mutation.target : mutation.target.parentElement;
1327
+ return target && !layer.contains(target) && !target.closest(".sia-table__viewport, [data-sia-native-scrollbar], .sia-scrollbar-track");
1328
+ })) scheduleScan();
1316
1329
  });
1317
- mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
1330
+ mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true, attributeFilter: ["class", "style", "hidden"] });
1318
1331
  window.addEventListener("resize", scheduleScan);
1319
1332
  window.addEventListener("scroll", scheduleUpdateAll, true);
1320
1333
  scheduleScan();
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  FloatingScrollbarProvider,
3
3
  Select
4
- } from "./chunk-3Q3S6CDZ.js";
4
+ } from "./chunk-NYJSSPIX.js";
5
5
  import {
6
6
  Icon
7
7
  } from "./chunk-XCVAVCIO.js";
@@ -52,6 +52,27 @@ interface CardProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
52
52
  description?: ReactNode;
53
53
  /** 主体之外的补充内容或操作区。 */
54
54
  extra?: ReactNode;
55
+ /**
56
+ * 点击卡片非交互区域切换选中,支持 Enter 和空格键;选中时显示右上角三角勾选标记。
57
+ * @defaultValue false
58
+ */
59
+ selectable?: boolean;
60
+ /** 受控选中状态,需在 onSelectedChange 中更新。 */
61
+ selected?: boolean;
62
+ /**
63
+ * 非受控初始选中状态。
64
+ * @defaultValue false
65
+ */
66
+ defaultSelected?: boolean;
67
+ /**
68
+ * 禁止切换选中,不禁用卡片内独立操作。
69
+ * @defaultValue false
70
+ */
71
+ disabled?: boolean;
72
+ /** 用户切换选中时通知新的布尔状态;禁用时不触发。 */
73
+ onSelectedChange?: (selected: boolean) => void;
74
+ /** 鼠标移入或键盘聚焦卡片时从底部滑入的操作区;触屏设备始终显示。 */
75
+ hoverActions?: ReactNode;
55
76
  /** 强调装饰样式。 */
56
77
  accent?: CardAccent;
57
78
  /** 强调装饰的颜色。 */
@@ -81,7 +102,7 @@ interface CardProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
81
102
  bodyStyle?: CSSProperties;
82
103
  }
83
104
  /** 卡片组件。 */
84
- declare function Card({ title, description, extra, accent, accentColor, collapsible, collapsed, defaultCollapsed, onCollapsedChange, bodyHeight, bodyClassName, bodyStyle, className, style, children, ...props }: CardProps): react.JSX.Element;
105
+ declare function Card({ title, description, extra, selectable, selected, defaultSelected, disabled, onSelectedChange, hoverActions, accent, accentColor, collapsible, collapsed, defaultCollapsed, onCollapsedChange, bodyHeight, bodyClassName, bodyStyle, className, style, children, onClick, onKeyDown, ...props }: CardProps): react.JSX.Element;
85
106
 
86
107
  declare const iconPaths: {
87
108
  "notepad-file": react.JSX.Element;
@@ -52,6 +52,27 @@ interface CardProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
52
52
  description?: ReactNode;
53
53
  /** 主体之外的补充内容或操作区。 */
54
54
  extra?: ReactNode;
55
+ /**
56
+ * 点击卡片非交互区域切换选中,支持 Enter 和空格键;选中时显示右上角三角勾选标记。
57
+ * @defaultValue false
58
+ */
59
+ selectable?: boolean;
60
+ /** 受控选中状态,需在 onSelectedChange 中更新。 */
61
+ selected?: boolean;
62
+ /**
63
+ * 非受控初始选中状态。
64
+ * @defaultValue false
65
+ */
66
+ defaultSelected?: boolean;
67
+ /**
68
+ * 禁止切换选中,不禁用卡片内独立操作。
69
+ * @defaultValue false
70
+ */
71
+ disabled?: boolean;
72
+ /** 用户切换选中时通知新的布尔状态;禁用时不触发。 */
73
+ onSelectedChange?: (selected: boolean) => void;
74
+ /** 鼠标移入或键盘聚焦卡片时从底部滑入的操作区;触屏设备始终显示。 */
75
+ hoverActions?: ReactNode;
55
76
  /** 强调装饰样式。 */
56
77
  accent?: CardAccent;
57
78
  /** 强调装饰的颜色。 */
@@ -81,7 +102,7 @@ interface CardProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
81
102
  bodyStyle?: CSSProperties;
82
103
  }
83
104
  /** 卡片组件。 */
84
- declare function Card({ title, description, extra, accent, accentColor, collapsible, collapsed, defaultCollapsed, onCollapsedChange, bodyHeight, bodyClassName, bodyStyle, className, style, children, ...props }: CardProps): react.JSX.Element;
105
+ declare function Card({ title, description, extra, selectable, selected, defaultSelected, disabled, onSelectedChange, hoverActions, accent, accentColor, collapsible, collapsed, defaultCollapsed, onCollapsedChange, bodyHeight, bodyClassName, bodyStyle, className, style, children, onClick, onKeyDown, ...props }: CardProps): react.JSX.Element;
85
106
 
86
107
  declare const iconPaths: {
87
108
  "notepad-file": react.JSX.Element;
package/dist/core.cjs CHANGED
@@ -1738,6 +1738,12 @@ function Card({
1738
1738
  title,
1739
1739
  description,
1740
1740
  extra,
1741
+ selectable = false,
1742
+ selected,
1743
+ defaultSelected = false,
1744
+ disabled = false,
1745
+ onSelectedChange,
1746
+ hoverActions,
1741
1747
  accent,
1742
1748
  accentColor,
1743
1749
  collapsible = false,
@@ -1750,9 +1756,19 @@ function Card({
1750
1756
  className = "",
1751
1757
  style,
1752
1758
  children,
1759
+ onClick,
1760
+ onKeyDown,
1753
1761
  ...props
1754
1762
  }) {
1755
1763
  const [internalCollapsed, setInternalCollapsed] = (0, import_react9.useState)(defaultCollapsed);
1764
+ const [internalSelected, setInternalSelected] = (0, import_react9.useState)(defaultSelected);
1765
+ const isSelected = selected ?? internalSelected;
1766
+ function toggleSelected() {
1767
+ if (!selectable || disabled) return;
1768
+ const next = !isSelected;
1769
+ if (selected === void 0) setInternalSelected(next);
1770
+ onSelectedChange?.(next);
1771
+ }
1756
1772
  const isCollapsed = collapsed ?? internalCollapsed;
1757
1773
  const hasHeader = title || extra || collapsible;
1758
1774
  const mergedStyle = accentColor ? { "--sia-card-accent": accentColor, ...style } : style;
@@ -1766,19 +1782,46 @@ function Card({
1766
1782
  accent || accentColor ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: `sia-card__accent${accent ? ` sia-card__accent--${accent}` : ""}`, "aria-hidden": "true" }) : null,
1767
1783
  title ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "sia-card__title", children: title }) : null
1768
1784
  ] });
1769
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("section", { className: `sia-card${isCollapsed ? " sia-card--collapsed" : ""} ${className}`.trim(), style: mergedStyle, ...withTitleTooltip(props), children: [
1770
- hasHeader ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("header", { className: "sia-card__header", children: [
1771
- collapsible ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { type: "button", className: "sia-card__collapse-trigger", "aria-expanded": !isCollapsed, onClick: toggleCollapsed, children: [
1772
- heading,
1773
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: isCollapsed ? "chevron-down" : "chevron-up", size: 16 })
1774
- ] }) : heading,
1775
- extra ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sia-card__extra", children: extra }) : null
1776
- ] }) : null,
1777
- !isCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1778
- description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "sia-card__description", children: description }) : null,
1779
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `sia-card__body ${bodyClassName}`.trim(), style: mergedBodyStyle, children })
1780
- ] }) : null
1781
- ] });
1785
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1786
+ "section",
1787
+ {
1788
+ className: `sia-card${isCollapsed ? " sia-card--collapsed" : ""}${selectable ? " sia-card--selectable" : ""}${selectable && isSelected ? " sia-card--selected" : ""}${hoverActions ? " sia-card--hover-actions" : ""} ${className}`.trim(),
1789
+ style: mergedStyle,
1790
+ role: selectable ? "checkbox" : void 0,
1791
+ "aria-checked": selectable ? isSelected : void 0,
1792
+ "aria-disabled": selectable ? disabled : void 0,
1793
+ tabIndex: selectable && !disabled ? 0 : void 0,
1794
+ ...withTitleTooltip(props),
1795
+ onClick: (event) => {
1796
+ onClick?.(event);
1797
+ const target = event.target;
1798
+ const interactive = target.closest('button, a, input, select, textarea, label, [role="button"], [role="checkbox"], [role="radio"], [role="switch"], [contenteditable="true"], [tabindex]');
1799
+ if (!event.defaultPrevented && (!interactive || interactive === event.currentTarget)) toggleSelected();
1800
+ },
1801
+ onKeyDown: (event) => {
1802
+ onKeyDown?.(event);
1803
+ if (!event.defaultPrevented && event.target === event.currentTarget && selectable && (event.key === "Enter" || event.key === " ")) {
1804
+ event.preventDefault();
1805
+ toggleSelected();
1806
+ }
1807
+ },
1808
+ children: [
1809
+ selectable && isSelected ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "sia-card__selected-corner", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: "check", size: 16 }) }) : null,
1810
+ hasHeader ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("header", { className: "sia-card__header", children: [
1811
+ collapsible ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { type: "button", className: "sia-card__collapse-trigger", "aria-expanded": !isCollapsed, onClick: toggleCollapsed, children: [
1812
+ heading,
1813
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: isCollapsed ? "chevron-down" : "chevron-up", size: 16 })
1814
+ ] }) : heading,
1815
+ extra ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sia-card__extra", children: extra }) : null
1816
+ ] }) : null,
1817
+ !isCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1818
+ description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "sia-card__description", children: description }) : null,
1819
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `sia-card__body ${bodyClassName}`.trim(), style: mergedBodyStyle, children }),
1820
+ hoverActions ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sia-card__hover-actions", onClick: (event) => event.stopPropagation(), children: hoverActions }) : null
1821
+ ] }) : null
1822
+ ]
1823
+ }
1824
+ );
1782
1825
  }
1783
1826
 
1784
1827
  // src/components/Tag.tsx
@@ -3414,7 +3457,17 @@ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
3414
3457
  };
3415
3458
  const scanTargets = () => {
3416
3459
  scanFrame = 0;
3417
- const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
3460
+ const managedSelector = ".sia-table__viewport, [data-sia-native-scrollbar], .sia-scrollbar-track, .sia-floating-scrollbar-layer";
3461
+ const discovered = [];
3462
+ if (!targetRef) {
3463
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
3464
+ acceptNode: (node) => node.matches(managedSelector) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT
3465
+ });
3466
+ for (let node = walker.nextNode(); node; node = walker.nextNode()) {
3467
+ if (node instanceof HTMLElement) discovered.push(node);
3468
+ }
3469
+ }
3470
+ const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...discovered]).filter((target) => target instanceof HTMLElement);
3418
3471
  const nextTargets = /* @__PURE__ */ new Set();
3419
3472
  candidates.forEach((target) => {
3420
3473
  if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
@@ -3432,9 +3485,12 @@ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
3432
3485
  scanFrame = window.requestAnimationFrame(scanTargets);
3433
3486
  };
3434
3487
  const mutationObserver = new MutationObserver((mutations) => {
3435
- if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
3488
+ if (mutations.some((mutation) => {
3489
+ const target = mutation.target instanceof Element ? mutation.target : mutation.target.parentElement;
3490
+ return target && !layer.contains(target) && !target.closest(".sia-table__viewport, [data-sia-native-scrollbar], .sia-scrollbar-track");
3491
+ })) scheduleScan();
3436
3492
  });
3437
- mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
3493
+ mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true, attributeFilter: ["class", "style", "hidden"] });
3438
3494
  window.addEventListener("resize", scheduleScan);
3439
3495
  window.addEventListener("scroll", scheduleUpdateAll, true);
3440
3496
  scheduleScan();
@@ -4904,13 +4960,13 @@ function TypographyContent({
4904
4960
  (0, import_react26.useEffect)(() => () => clearTimeout(timer.current), []);
4905
4961
  (0, import_react26.useLayoutEffect)(() => {
4906
4962
  const element = contentRef.current;
4907
- if (!element || !ellipsis || editing || expanded) return;
4963
+ if (!element || !ellipsis || !expandable || editing || expanded) return;
4908
4964
  const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
4909
4965
  measure();
4910
4966
  const observer = new ResizeObserver(measure);
4911
4967
  observer.observe(element);
4912
4968
  return () => observer.disconnect();
4913
- }, [content, ellipsis, rows, editing, expanded]);
4969
+ }, [content, ellipsis, rows, expandable, editing, expanded]);
4914
4970
  async function copy() {
4915
4971
  try {
4916
4972
  const text = typeof copyable === "object" ? copyable.text ?? contentRef.current?.textContent ?? "" : contentRef.current?.textContent ?? "";
package/dist/core.css CHANGED
@@ -2541,6 +2541,71 @@ fieldset:disabled .sia-input-number__floating-placeholder {
2541
2541
  .sia-card--collapsed .sia-card__header {
2542
2542
  border-bottom-color: transparent;
2543
2543
  }
2544
+ .sia-card--selectable {
2545
+ position: relative;
2546
+ cursor: pointer;
2547
+ }
2548
+ .sia-card__selected-corner {
2549
+ position: absolute;
2550
+ top: 0;
2551
+ right: 0;
2552
+ width: 40px;
2553
+ height: 40px;
2554
+ background: var(--sia-color-primary);
2555
+ color: white;
2556
+ clip-path: polygon(0 0, 100% 0, 100% 100%);
2557
+ border-top-right-radius: var(--sia-radius);
2558
+ pointer-events: none;
2559
+ z-index: 1;
2560
+ }
2561
+ .sia-card__selected-corner > .sia-icon {
2562
+ position: absolute;
2563
+ top: 4px;
2564
+ right: 4px;
2565
+ }
2566
+ .sia-card--selectable[aria-disabled=true] {
2567
+ cursor: default;
2568
+ }
2569
+ .sia-card.sia-card--selected {
2570
+ border-color: var(--sia-color-primary);
2571
+ box-shadow: inset 0 0 0 1px var(--sia-color-primary);
2572
+ }
2573
+ .sia-card--selectable:focus-visible {
2574
+ outline: 2px solid var(--sia-color-primary);
2575
+ outline-offset: 2px;
2576
+ }
2577
+ .sia-card--hover-actions {
2578
+ position: relative;
2579
+ overflow: hidden;
2580
+ }
2581
+ .sia-card__hover-actions {
2582
+ position: absolute;
2583
+ inset: auto 0 0;
2584
+ padding: 8px 16px;
2585
+ background: var(--sia-color-surface);
2586
+ border-top: 1px solid var(--sia-color-border);
2587
+ transform: translateY(100%);
2588
+ visibility: hidden;
2589
+ transition: transform 180ms ease, visibility 180ms;
2590
+ }
2591
+ .sia-card--hover-actions:hover > .sia-card__hover-actions,
2592
+ .sia-card--hover-actions:has(:focus-visible) > .sia-card__hover-actions,
2593
+ .sia-card--hover-actions:focus-visible > .sia-card__hover-actions {
2594
+ transform: translateY(0);
2595
+ visibility: visible;
2596
+ }
2597
+ @media (hover: none) {
2598
+ .sia-card__hover-actions {
2599
+ position: static;
2600
+ transform: none;
2601
+ visibility: visible;
2602
+ }
2603
+ }
2604
+ @media (prefers-reduced-motion: reduce) {
2605
+ .sia-card__hover-actions {
2606
+ transition: none;
2607
+ }
2608
+ }
2544
2609
  .sia-alert {
2545
2610
  display: flex;
2546
2611
  align-items: flex-start;
package/dist/core.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { d as Breadcrumb, e as BreadcrumbItem, f as BreadcrumbProps, h as Card, i as CardAccent, j as CardProps, n as Collapse, o as CollapseItem, p as CollapseKey, q as CollapseProps, x as FilledIconName, y as FloatButton, z as FloatButtonBackTopProps, A as FloatButtonGroupProps, E as FloatButtonProps, G as FloatButtonShape, K as Icon, L as IconName, M as IconProps, N as IconVariant, U as Input, V as InputProps, a0 as MessageConfig, a1 as MessageHandle, a2 as MessageKey, a3 as MessageType, ab as Progress, ac as ProgressProps, ad as ProgressStatus, ag as Segmented, ah as SegmentedOption, ai as SegmentedProps, aj as SegmentedValue, aq as TabItem, ar as Tabs, at as TabsOrientation, au as TabsPosition, av as TabsProps, aw as TabsType, ax as Tag, ay as TagProps, az as TagSize, T as TagStatus, aA as TagVariant, aE as Toolbar, aF as ToolbarItem, aG as ToolbarProps, aR as Typography, aS as TypographyLinkProps, aT as TypographyProps, aU as TypographyTitleProps, aV as TypographyType, aW as Upload, aX as UploadChangeInfo, aY as UploadDraggerProps, aZ as UploadFile, a_ as UploadFileStatus, b1 as UploadProps, b5 as UploadRequestOptions, b9 as message } from './core-C2IieVNm.cjs';
1
+ export { d as Breadcrumb, e as BreadcrumbItem, f as BreadcrumbProps, h as Card, i as CardAccent, j as CardProps, n as Collapse, o as CollapseItem, p as CollapseKey, q as CollapseProps, x as FilledIconName, y as FloatButton, z as FloatButtonBackTopProps, A as FloatButtonGroupProps, E as FloatButtonProps, G as FloatButtonShape, K as Icon, L as IconName, M as IconProps, N as IconVariant, U as Input, V as InputProps, a0 as MessageConfig, a1 as MessageHandle, a2 as MessageKey, a3 as MessageType, ab as Progress, ac as ProgressProps, ad as ProgressStatus, ag as Segmented, ah as SegmentedOption, ai as SegmentedProps, aj as SegmentedValue, aq as TabItem, ar as Tabs, at as TabsOrientation, au as TabsPosition, av as TabsProps, aw as TabsType, ax as Tag, ay as TagProps, az as TagSize, T as TagStatus, aA as TagVariant, aE as Toolbar, aF as ToolbarItem, aG as ToolbarProps, aR as Typography, aS as TypographyLinkProps, aT as TypographyProps, aU as TypographyTitleProps, aV as TypographyType, aW as Upload, aX as UploadChangeInfo, aY as UploadDraggerProps, aZ as UploadFile, a_ as UploadFileStatus, b1 as UploadProps, b5 as UploadRequestOptions, b9 as message } from './core-CADzSGab.cjs';
2
2
  export { f as Button, B as ButtonProps, e as ButtonSize, g as ButtonVariant, h as Modal, d as ModalActionResult, M as ModalOpenConfig, i as ModalProps, j as ModalType, a as OverlayApiHandle, k as Select, S as SelectOption, c as SelectProps, m as SelectValue } from './Select-YJbT-MF1.cjs';
3
3
  import 'react';
4
4
  import './shared-Bx4B28Wh.cjs';
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { d as Breadcrumb, e as BreadcrumbItem, f as BreadcrumbProps, h as Card, i as CardAccent, j as CardProps, n as Collapse, o as CollapseItem, p as CollapseKey, q as CollapseProps, x as FilledIconName, y as FloatButton, z as FloatButtonBackTopProps, A as FloatButtonGroupProps, E as FloatButtonProps, G as FloatButtonShape, K as Icon, L as IconName, M as IconProps, N as IconVariant, U as Input, V as InputProps, a0 as MessageConfig, a1 as MessageHandle, a2 as MessageKey, a3 as MessageType, ab as Progress, ac as ProgressProps, ad as ProgressStatus, ag as Segmented, ah as SegmentedOption, ai as SegmentedProps, aj as SegmentedValue, aq as TabItem, ar as Tabs, at as TabsOrientation, au as TabsPosition, av as TabsProps, aw as TabsType, ax as Tag, ay as TagProps, az as TagSize, T as TagStatus, aA as TagVariant, aE as Toolbar, aF as ToolbarItem, aG as ToolbarProps, aR as Typography, aS as TypographyLinkProps, aT as TypographyProps, aU as TypographyTitleProps, aV as TypographyType, aW as Upload, aX as UploadChangeInfo, aY as UploadDraggerProps, aZ as UploadFile, a_ as UploadFileStatus, b1 as UploadProps, b5 as UploadRequestOptions, b9 as message } from './core-ZmKnvCFV.js';
1
+ export { d as Breadcrumb, e as BreadcrumbItem, f as BreadcrumbProps, h as Card, i as CardAccent, j as CardProps, n as Collapse, o as CollapseItem, p as CollapseKey, q as CollapseProps, x as FilledIconName, y as FloatButton, z as FloatButtonBackTopProps, A as FloatButtonGroupProps, E as FloatButtonProps, G as FloatButtonShape, K as Icon, L as IconName, M as IconProps, N as IconVariant, U as Input, V as InputProps, a0 as MessageConfig, a1 as MessageHandle, a2 as MessageKey, a3 as MessageType, ab as Progress, ac as ProgressProps, ad as ProgressStatus, ag as Segmented, ah as SegmentedOption, ai as SegmentedProps, aj as SegmentedValue, aq as TabItem, ar as Tabs, at as TabsOrientation, au as TabsPosition, av as TabsProps, aw as TabsType, ax as Tag, ay as TagProps, az as TagSize, T as TagStatus, aA as TagVariant, aE as Toolbar, aF as ToolbarItem, aG as ToolbarProps, aR as Typography, aS as TypographyLinkProps, aT as TypographyProps, aU as TypographyTitleProps, aV as TypographyType, aW as Upload, aX as UploadChangeInfo, aY as UploadDraggerProps, aZ as UploadFile, a_ as UploadFileStatus, b1 as UploadProps, b5 as UploadRequestOptions, b9 as message } from './core-wsymjzoC.js';
2
2
  export { f as Button, B as ButtonProps, e as ButtonSize, g as ButtonVariant, h as Modal, d as ModalActionResult, M as ModalOpenConfig, i as ModalProps, j as ModalType, a as OverlayApiHandle, k as Select, S as SelectOption, c as SelectProps, m as SelectValue } from './Select-CCrPqULn.js';
3
3
  import 'react';
4
4
  import './shared-Bx4B28Wh.js';
package/dist/core.js CHANGED
@@ -10,12 +10,12 @@ import {
10
10
  Typography,
11
11
  Upload,
12
12
  message
13
- } from "./chunk-IPDCEXQO.js";
13
+ } from "./chunk-KXPNW4E6.js";
14
14
  import "./chunk-SMCYEPBL.js";
15
15
  import {
16
16
  Modal,
17
17
  Select
18
- } from "./chunk-3Q3S6CDZ.js";
18
+ } from "./chunk-NYJSSPIX.js";
19
19
  import {
20
20
  Icon,
21
21
  Input,