@sia.soul/sia-react-ui 0.1.45 → 0.1.47

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.
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-H7IAG72O.js";
15
15
 
16
16
  // src/components/DatePicker.tsx
17
- import { useEffect, useId, useMemo, useRef as useRef2, useState } from "react";
17
+ import { useEffect, useId, useLayoutEffect as useLayoutEffect2, useMemo, useRef as useRef2, useState } from "react";
18
18
 
19
19
  // src/components/DatePickerPanel.tsx
20
20
  import { useLayoutEffect, useRef } from "react";
@@ -496,6 +496,24 @@ function DateRangePicker({
496
496
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
497
497
  const [draftValue, setDraftValue] = useState(currentValue);
498
498
  const [activeIndex, setActiveIndex] = useState(endpointDisabled[0] || currentValue[0] && !currentValue[1] ? 1 : 0);
499
+ const indicatorRef = useRef2(null);
500
+ useLayoutEffect2(() => {
501
+ const field = rootRef.current?.querySelector(`[data-range-endpoint="${activeIndex}"]`);
502
+ const indicator = indicatorRef.current;
503
+ if (!field || !indicator) return;
504
+ const alignIndicator = () => {
505
+ indicator.style.transform = `translateX(${field.offsetLeft}px)`;
506
+ indicator.style.width = `${field.offsetWidth}px`;
507
+ };
508
+ alignIndicator();
509
+ const observer = new ResizeObserver(alignIndicator);
510
+ const trigger = field.parentElement;
511
+ if (trigger) {
512
+ observer.observe(trigger);
513
+ for (const child of trigger.children) if (child !== indicator) observer.observe(child);
514
+ }
515
+ return () => observer.disconnect();
516
+ });
499
517
  const [confirmedIndex, setConfirmedIndex] = useState(null);
500
518
  const [presetSelected, setPresetSelected] = useState(false);
501
519
  const [hoverDate, setHoverDate] = useState("");
@@ -762,6 +780,7 @@ function DateRangePicker({
762
780
  /* @__PURE__ */ jsx2("span", { className: `sia-picker-range-control__value${displayValue[1] ? "" : " is-placeholder"}`, children: displayValue[1] ? formatValue(displayValue[1]) : placeholder[1] }),
763
781
  endFloating.label
764
782
  ] }),
783
+ /* @__PURE__ */ jsx2("span", { ref: indicatorRef, className: "sia-picker-range-control__indicator", "aria-hidden": "true" }),
765
784
  /* @__PURE__ */ jsx2("span", { className: "sia-picker__icon", "aria-hidden": "true", children: suffixIcon ?? /* @__PURE__ */ jsx2(Icon, { name: "calendar", size: 16 }) })
766
785
  ]
767
786
  }
package/dist/core.css CHANGED
@@ -121,15 +121,26 @@ fieldset:disabled .sia-input-number__floating-placeholder {
121
121
  min-width: 0;
122
122
  height: 100%;
123
123
  }
124
- .sia-picker-range-control__field.is-active::after {
125
- content: "";
124
+ .sia-picker-range-control > .sia-picker__trigger {
125
+ position: relative;
126
+ }
127
+ .sia-picker-range-control__indicator {
126
128
  position: absolute;
127
- right: 0;
128
129
  bottom: -1px;
129
130
  left: 0;
130
131
  height: 3px;
131
132
  background: var(--sia-color-primary);
132
133
  pointer-events: none;
134
+ visibility: hidden;
135
+ }
136
+ .sia-picker-range-control.is-open .sia-picker-range-control__indicator {
137
+ visibility: visible;
138
+ transition: transform 220ms ease, width 220ms ease;
139
+ }
140
+ @media (prefers-reduced-motion: reduce) {
141
+ .sia-picker-range-control.is-open .sia-picker-range-control__indicator {
142
+ transition: none;
143
+ }
133
144
  }
134
145
  .sia-picker-range-control__field.sia-placeholder-floating > .is-placeholder {
135
146
  color: transparent;
package/dist/index.cjs CHANGED
@@ -5915,6 +5915,7 @@ var DrawerRoot = (0, import_react28.forwardRef)(function Drawer({
5915
5915
  ...props
5916
5916
  }, forwardedRef) {
5917
5917
  const localRef = (0, import_react28.useRef)(null);
5918
+ const bodyRef = (0, import_react28.useRef)(null);
5918
5919
  const titleId = (0, import_react28.useId)();
5919
5920
  const drawerId = (0, import_react28.useId)();
5920
5921
  const parentStack = (0, import_react28.useContext)(DrawerStackContext);
@@ -6008,7 +6009,8 @@ var DrawerRoot = (0, import_react28.forwardRef)(function Drawer({
6008
6009
  ] }),
6009
6010
  extra ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "sia-drawer__extra", children: extra }) : null
6010
6011
  ] }),
6011
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "sia-drawer__body", children }),
6012
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { ref: bodyRef, className: "sia-drawer__body", children }),
6013
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FloatingScrollbarProvider, { targetRef: bodyRef }),
6012
6014
  footer ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "sia-drawer__footer", children: footer }) : null
6013
6015
  ]
6014
6016
  }
@@ -7487,6 +7489,24 @@ function DateRangePicker({
7487
7489
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
7488
7490
  const [draftValue, setDraftValue] = (0, import_react34.useState)(currentValue);
7489
7491
  const [activeIndex, setActiveIndex] = (0, import_react34.useState)(endpointDisabled[0] || currentValue[0] && !currentValue[1] ? 1 : 0);
7492
+ const indicatorRef = (0, import_react34.useRef)(null);
7493
+ (0, import_react34.useLayoutEffect)(() => {
7494
+ const field = rootRef.current?.querySelector(`[data-range-endpoint="${activeIndex}"]`);
7495
+ const indicator = indicatorRef.current;
7496
+ if (!field || !indicator) return;
7497
+ const alignIndicator = () => {
7498
+ indicator.style.transform = `translateX(${field.offsetLeft}px)`;
7499
+ indicator.style.width = `${field.offsetWidth}px`;
7500
+ };
7501
+ alignIndicator();
7502
+ const observer = new ResizeObserver(alignIndicator);
7503
+ const trigger = field.parentElement;
7504
+ if (trigger) {
7505
+ observer.observe(trigger);
7506
+ for (const child of trigger.children) if (child !== indicator) observer.observe(child);
7507
+ }
7508
+ return () => observer.disconnect();
7509
+ });
7490
7510
  const [confirmedIndex, setConfirmedIndex] = (0, import_react34.useState)(null);
7491
7511
  const [presetSelected, setPresetSelected] = (0, import_react34.useState)(false);
7492
7512
  const [hoverDate, setHoverDate] = (0, import_react34.useState)("");
@@ -7753,6 +7773,7 @@ function DateRangePicker({
7753
7773
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: `sia-picker-range-control__value${displayValue[1] ? "" : " is-placeholder"}`, children: displayValue[1] ? formatValue2(displayValue[1]) : placeholder[1] }),
7754
7774
  endFloating.label
7755
7775
  ] }),
7776
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { ref: indicatorRef, className: "sia-picker-range-control__indicator", "aria-hidden": "true" }),
7756
7777
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "sia-picker__icon", "aria-hidden": "true", children: suffixIcon ?? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Icon, { name: "calendar", size: 16 }) })
7757
7778
  ]
7758
7779
  }
@@ -11994,6 +12015,12 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
11994
12015
  ctx.clearRect(0, 0, width, height);
11995
12016
  const style = getComputedStyle(scroller);
11996
12017
  const foreground = style.color;
12018
+ const readyCells = /* @__PURE__ */ new Map();
12019
+ scroller.querySelectorAll("tr[data-canvas-row-index]").forEach((element) => {
12020
+ const keys = /* @__PURE__ */ new Set();
12021
+ element.querySelectorAll('[data-canvas-dom-ready="true"]').forEach((cell) => keys.add(cell.dataset.columnKey));
12022
+ readyCells.set(Number(element.dataset.canvasRowIndex), keys);
12023
+ });
11997
12024
  ctx.font = `${style.fontSize} ${style.fontFamily}`;
11998
12025
  ctx.textBaseline = "middle";
11999
12026
  const leftWidth = columns.reduce((n, c) => n + (normalizeFixed(c.fixed) === "left" ? widths.get(c.key) ?? 160 : 0), 0);
@@ -12011,7 +12038,7 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
12011
12038
  const first = Math.max(0, Math.floor(scroller.scrollTop / rowHeight));
12012
12039
  const last = Math.min(rows.length, Math.ceil((scroller.scrollTop + height) / rowHeight));
12013
12040
  for (const { column, x, cellWidth, fixed } of geometry) {
12014
- if (x + cellWidth <= 0 || x >= width || !column.canvasRender && column.render) continue;
12041
+ if (x + cellWidth <= 0 || x >= width) continue;
12015
12042
  const clipLeft = Math.max(x, fixed ? 0 : leftWidth);
12016
12043
  const clipRight = Math.min(x + cellWidth, fixed ? width : width - rightWidth);
12017
12044
  if (clipRight <= clipLeft) continue;
@@ -12021,12 +12048,26 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
12021
12048
  ctx.clip();
12022
12049
  for (let index = first; index < last; index++) {
12023
12050
  const row = rows[index];
12024
- const value = getTableValue(row.record, column.dataIndex, column.code ?? column.key);
12025
- const content = column.canvasRender ? column.canvasRender(value, row.record, row.sourceIndex, { row, rowIndex: index, column }) : { text: value == null ? "" : String(value) };
12026
- if (!content?.text) continue;
12027
12051
  const y = headerHeight + index * rowHeight - scroller.scrollTop + rowHeight / 2;
12028
- const available = Math.max(0, cellWidth - (content.background ? 32 : 16));
12029
- let text = content.text;
12052
+ if (!column.canvasRender && column.render) {
12053
+ if (!readyCells.get(index)?.has(column.key)) {
12054
+ const skeletonWidth = Math.max(0, Math.min(cellWidth - 24, 120));
12055
+ const skeletonX = column.align === "right" ? x + cellWidth - skeletonWidth - 8 : column.align === "center" ? x + (cellWidth - skeletonWidth) / 2 : x + 8;
12056
+ ctx.save();
12057
+ ctx.fillStyle = foreground;
12058
+ ctx.globalAlpha = 0.12;
12059
+ ctx.beginPath();
12060
+ ctx.roundRect(skeletonX, y - 6, skeletonWidth, 12, 4);
12061
+ ctx.fill();
12062
+ ctx.restore();
12063
+ }
12064
+ continue;
12065
+ }
12066
+ const value = getTableValue(row.record, column.dataIndex, column.code ?? column.key);
12067
+ const content2 = column.canvasRender ? column.canvasRender(value, row.record, row.sourceIndex, { row, rowIndex: index, column }) : { text: value == null ? "" : String(value) };
12068
+ if (!content2?.text) continue;
12069
+ const available = Math.max(0, cellWidth - (content2.background ? 32 : 16));
12070
+ let text = content2.text;
12030
12071
  if (ctx.measureText(text).width > available) {
12031
12072
  let lo = 0, hi = text.length;
12032
12073
  while (lo < hi) {
@@ -12037,16 +12078,16 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
12037
12078
  text = text.slice(0, lo) + "\u2026";
12038
12079
  }
12039
12080
  const textWidth = ctx.measureText(text).width;
12040
- const total = textWidth + (content.background ? 16 : 0);
12081
+ const total = textWidth + (content2.background ? 16 : 0);
12041
12082
  const tx = column.align === "right" ? x + cellWidth - total - 8 : column.align === "center" ? x + (cellWidth - total) / 2 : x + 8;
12042
- if (content.background) {
12043
- ctx.fillStyle = content.background;
12083
+ if (content2.background) {
12084
+ ctx.fillStyle = content2.background;
12044
12085
  ctx.beginPath();
12045
12086
  ctx.roundRect(tx, y - 12, total, 24, 4);
12046
12087
  ctx.fill();
12047
12088
  }
12048
- ctx.fillStyle = content.color ?? foreground;
12049
- ctx.fillText(text, tx + (content.background ? 8 : 0), y);
12089
+ ctx.fillStyle = content2.color ?? foreground;
12090
+ ctx.fillText(text, tx + (content2.background ? 8 : 0), y);
12050
12091
  }
12051
12092
  ctx.restore();
12052
12093
  }
@@ -12057,6 +12098,8 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
12057
12098
  scroller.addEventListener("scroll", schedule, { passive: true });
12058
12099
  const resize = new ResizeObserver(schedule);
12059
12100
  resize.observe(scroller);
12101
+ const content = new MutationObserver(schedule);
12102
+ content.observe(scroller, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-canvas-row-index", "data-canvas-dom-ready", "data-column-key"] });
12060
12103
  const theme = new MutationObserver(schedule);
12061
12104
  theme.observe(document.documentElement, { attributes: true });
12062
12105
  window.addEventListener("resize", schedule);
@@ -12064,6 +12107,7 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
12064
12107
  return () => {
12065
12108
  cancelAnimationFrame(frame);
12066
12109
  resize.disconnect();
12110
+ content.disconnect();
12067
12111
  theme.disconnect();
12068
12112
  scroller.removeEventListener("scroll", schedule);
12069
12113
  window.removeEventListener("resize", schedule);
@@ -14613,6 +14657,7 @@ var TableBodyRow = (0, import_react52.memo)(function TableBodyRow2({
14613
14657
  return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
14614
14658
  "tr",
14615
14659
  {
14660
+ "data-canvas-row-index": canvas ? rowIndex : void 0,
14616
14661
  className: `sia-table__row${striped && rowIndex % 2 === 1 ? " sia-table__row--striped" : ""} ${className}`.trim(),
14617
14662
  style: { height: rowHeight },
14618
14663
  onClick,
@@ -14638,6 +14683,7 @@ var TableBodyRow = (0, import_react52.memo)(function TableBodyRow2({
14638
14683
  "td",
14639
14684
  {
14640
14685
  "data-column-key": column.key,
14686
+ "data-canvas-dom-ready": canvas && (pluginCellProps.content !== void 0 || !column.canvasRender && column.render) ? "true" : void 0,
14641
14687
  "aria-label": canvas ? column.canvasRender?.(value, row.record, row.sourceIndex, { row, rowIndex, column })?.text ?? (value == null ? "" : String(value)) : void 0,
14642
14688
  rowSpan: pluginCellProps.rowSpan,
14643
14689
  colSpan: pluginCellProps.colSpan,
package/dist/index.css CHANGED
@@ -121,15 +121,26 @@ fieldset:disabled .sia-input-number__floating-placeholder {
121
121
  min-width: 0;
122
122
  height: 100%;
123
123
  }
124
- .sia-picker-range-control__field.is-active::after {
125
- content: "";
124
+ .sia-picker-range-control > .sia-picker__trigger {
125
+ position: relative;
126
+ }
127
+ .sia-picker-range-control__indicator {
126
128
  position: absolute;
127
- right: 0;
128
129
  bottom: -1px;
129
130
  left: 0;
130
131
  height: 3px;
131
132
  background: var(--sia-color-primary);
132
133
  pointer-events: none;
134
+ visibility: hidden;
135
+ }
136
+ .sia-picker-range-control.is-open .sia-picker-range-control__indicator {
137
+ visibility: visible;
138
+ transition: transform 220ms ease, width 220ms ease;
139
+ }
140
+ @media (prefers-reduced-motion: reduce) {
141
+ .sia-picker-range-control.is-open .sia-picker-range-control__indicator {
142
+ transition: none;
143
+ }
133
144
  }
134
145
  .sia-picker-range-control__field.sia-placeholder-floating > .is-placeholder {
135
146
  color: transparent;
package/dist/index.d.cts CHANGED
@@ -5,7 +5,7 @@ import { HTMLAttributes, ReactNode, CSSProperties, ElementType, FormHTMLAttribut
5
5
  import { C as ControlSize, I as InputPlaceholderMode, a as ControlStatus } from './shared-Bx4B28Wh.cjs';
6
6
  import { O as OverlayContainer, a as OverlayApiHandle, M as ModalOpenConfig, S as SelectOption, b as SelectChangeValue, c as SelectProps, d as ModalActionResult, B as ButtonProps, e as ButtonSize } from './Select-YJbT-MF1.cjs';
7
7
  export { f as Button, g as ButtonVariant, h as Modal, i as ModalProps, j as ModalType, k as Select, l as SelectMode, m as SelectValue } from './Select-YJbT-MF1.cjs';
8
- export { D as DatePicker, a as DatePickerDisabledInfo, b as DatePickerPreset, c as DatePickerProps, d as DatePickerShowTime, e as DatePickerType, f as DatePickerValue, g as DateRangePickerPreset, h as DateRangePickerProps, S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-2galnCvZ.cjs';
8
+ export { D as DatePicker, a as DatePickerDisabledInfo, b as DatePickerPreset, c as DatePickerProps, d as DatePickerShowTime, e as DatePickerType, f as DatePickerValue, g as DateRangePickerPreset, h as DateRangePickerProps, S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-CyfCT32j.cjs';
9
9
  export { RichTextContent, RichTextContentFormat, RichTextContentProps, RichTextEditor, RichTextEditorProps, RichTextImagePasteHandler, RichTextToolbar } from './rich-text-editor.cjs';
10
10
  export { MarkdownEditor, MarkdownEditorMode, MarkdownEditorProps } from './markdown-editor.cjs';
11
11
  import * as Monaco from 'monaco-editor';
@@ -585,7 +585,7 @@ interface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
585
585
  open: boolean;
586
586
  /** 标题内容,可传入文本或 React 节点。 */
587
587
  title?: ReactNode;
588
- /** 子内容;组件嵌套内容或当前节点的子项。 */
588
+ /** 抽屉主体内容;溢出时默认使用不占布局空间的浮动滚动条,标题及底部操作区保持固定。 */
589
589
  children?: ReactNode;
590
590
  /** 主体之外的补充内容或操作区。 */
591
591
  extra?: ReactNode;
@@ -640,7 +640,7 @@ interface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
640
640
  interface DrawerOpenConfig extends Omit<DrawerProps, "open"> {
641
641
  }
642
642
  declare function openDrawer(config: DrawerOpenConfig): OverlayApiHandle<DrawerOpenConfig>;
643
- /** 抽屉组件。 */
643
+ /** 从屏幕边缘展开的抽屉;主体默认使用浮动滚动条,支持四个方向、嵌套推移及静态 API 调用。 */
644
644
  declare const Drawer: react.ForwardRefExoticComponent<DrawerProps & react.RefAttributes<HTMLDivElement>> & {
645
645
  /** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
646
646
  open: typeof openDrawer;
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import { HTMLAttributes, ReactNode, CSSProperties, ElementType, FormHTMLAttribut
5
5
  import { C as ControlSize, I as InputPlaceholderMode, a as ControlStatus } from './shared-Bx4B28Wh.js';
6
6
  import { O as OverlayContainer, a as OverlayApiHandle, M as ModalOpenConfig, S as SelectOption, b as SelectChangeValue, c as SelectProps, d as ModalActionResult, B as ButtonProps, e as ButtonSize } from './Select-CCrPqULn.js';
7
7
  export { f as Button, g as ButtonVariant, h as Modal, i as ModalProps, j as ModalType, k as Select, l as SelectMode, m as SelectValue } from './Select-CCrPqULn.js';
8
- export { D as DatePicker, a as DatePickerDisabledInfo, b as DatePickerPreset, c as DatePickerProps, d as DatePickerShowTime, e as DatePickerType, f as DatePickerValue, g as DateRangePickerPreset, h as DateRangePickerProps, S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-Dtj6XF9I.js';
8
+ export { D as DatePicker, a as DatePickerDisabledInfo, b as DatePickerPreset, c as DatePickerProps, d as DatePickerShowTime, e as DatePickerType, f as DatePickerValue, g as DateRangePickerPreset, h as DateRangePickerProps, S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-B1ZWIHoe.js';
9
9
  export { RichTextContent, RichTextContentFormat, RichTextContentProps, RichTextEditor, RichTextEditorProps, RichTextImagePasteHandler, RichTextToolbar } from './rich-text-editor.js';
10
10
  export { MarkdownEditor, MarkdownEditorMode, MarkdownEditorProps } from './markdown-editor.js';
11
11
  import * as Monaco from 'monaco-editor';
@@ -585,7 +585,7 @@ interface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
585
585
  open: boolean;
586
586
  /** 标题内容,可传入文本或 React 节点。 */
587
587
  title?: ReactNode;
588
- /** 子内容;组件嵌套内容或当前节点的子项。 */
588
+ /** 抽屉主体内容;溢出时默认使用不占布局空间的浮动滚动条,标题及底部操作区保持固定。 */
589
589
  children?: ReactNode;
590
590
  /** 主体之外的补充内容或操作区。 */
591
591
  extra?: ReactNode;
@@ -640,7 +640,7 @@ interface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
640
640
  interface DrawerOpenConfig extends Omit<DrawerProps, "open"> {
641
641
  }
642
642
  declare function openDrawer(config: DrawerOpenConfig): OverlayApiHandle<DrawerOpenConfig>;
643
- /** 抽屉组件。 */
643
+ /** 从屏幕边缘展开的抽屉;主体默认使用浮动滚动条,支持四个方向、嵌套推移及静态 API 调用。 */
644
644
  declare const Drawer: react.ForwardRefExoticComponent<DrawerProps & react.RefAttributes<HTMLDivElement>> & {
645
645
  /** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
646
646
  open: typeof openDrawer;
package/dist/index.js CHANGED
@@ -95,7 +95,7 @@ import {
95
95
  DatePicker,
96
96
  SelectDateRange,
97
97
  TimePanel
98
- } from "./chunk-QIXU7N4X.js";
98
+ } from "./chunk-E4RMSZOC.js";
99
99
  import {
100
100
  Checkbox,
101
101
  FloatingScrollbarProvider,
@@ -1245,6 +1245,7 @@ var DrawerRoot = forwardRef(function Drawer({
1245
1245
  ...props
1246
1246
  }, forwardedRef) {
1247
1247
  const localRef = useRef4(null);
1248
+ const bodyRef = useRef4(null);
1248
1249
  const titleId = useId2();
1249
1250
  const drawerId = useId2();
1250
1251
  const parentStack = useContext(DrawerStackContext);
@@ -1338,7 +1339,8 @@ var DrawerRoot = forwardRef(function Drawer({
1338
1339
  ] }),
1339
1340
  extra ? /* @__PURE__ */ jsx8("div", { className: "sia-drawer__extra", children: extra }) : null
1340
1341
  ] }),
1341
- /* @__PURE__ */ jsx8("div", { className: "sia-drawer__body", children }),
1342
+ /* @__PURE__ */ jsx8("div", { ref: bodyRef, className: "sia-drawer__body", children }),
1343
+ /* @__PURE__ */ jsx8(FloatingScrollbarProvider, { targetRef: bodyRef }),
1342
1344
  footer ? /* @__PURE__ */ jsx8("div", { className: "sia-drawer__footer", children: footer }) : null
1343
1345
  ]
1344
1346
  }
@@ -4785,6 +4787,12 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
4785
4787
  ctx.clearRect(0, 0, width, height);
4786
4788
  const style = getComputedStyle(scroller);
4787
4789
  const foreground = style.color;
4790
+ const readyCells = /* @__PURE__ */ new Map();
4791
+ scroller.querySelectorAll("tr[data-canvas-row-index]").forEach((element) => {
4792
+ const keys = /* @__PURE__ */ new Set();
4793
+ element.querySelectorAll('[data-canvas-dom-ready="true"]').forEach((cell) => keys.add(cell.dataset.columnKey));
4794
+ readyCells.set(Number(element.dataset.canvasRowIndex), keys);
4795
+ });
4788
4796
  ctx.font = `${style.fontSize} ${style.fontFamily}`;
4789
4797
  ctx.textBaseline = "middle";
4790
4798
  const leftWidth = columns.reduce((n, c) => n + (normalizeFixed(c.fixed) === "left" ? widths.get(c.key) ?? 160 : 0), 0);
@@ -4802,7 +4810,7 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
4802
4810
  const first = Math.max(0, Math.floor(scroller.scrollTop / rowHeight));
4803
4811
  const last = Math.min(rows.length, Math.ceil((scroller.scrollTop + height) / rowHeight));
4804
4812
  for (const { column, x, cellWidth, fixed } of geometry) {
4805
- if (x + cellWidth <= 0 || x >= width || !column.canvasRender && column.render) continue;
4813
+ if (x + cellWidth <= 0 || x >= width) continue;
4806
4814
  const clipLeft = Math.max(x, fixed ? 0 : leftWidth);
4807
4815
  const clipRight = Math.min(x + cellWidth, fixed ? width : width - rightWidth);
4808
4816
  if (clipRight <= clipLeft) continue;
@@ -4812,12 +4820,26 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
4812
4820
  ctx.clip();
4813
4821
  for (let index = first; index < last; index++) {
4814
4822
  const row = rows[index];
4815
- const value = getTableValue(row.record, column.dataIndex, column.code ?? column.key);
4816
- const content = column.canvasRender ? column.canvasRender(value, row.record, row.sourceIndex, { row, rowIndex: index, column }) : { text: value == null ? "" : String(value) };
4817
- if (!content?.text) continue;
4818
4823
  const y = headerHeight + index * rowHeight - scroller.scrollTop + rowHeight / 2;
4819
- const available = Math.max(0, cellWidth - (content.background ? 32 : 16));
4820
- let text = content.text;
4824
+ if (!column.canvasRender && column.render) {
4825
+ if (!readyCells.get(index)?.has(column.key)) {
4826
+ const skeletonWidth = Math.max(0, Math.min(cellWidth - 24, 120));
4827
+ const skeletonX = column.align === "right" ? x + cellWidth - skeletonWidth - 8 : column.align === "center" ? x + (cellWidth - skeletonWidth) / 2 : x + 8;
4828
+ ctx.save();
4829
+ ctx.fillStyle = foreground;
4830
+ ctx.globalAlpha = 0.12;
4831
+ ctx.beginPath();
4832
+ ctx.roundRect(skeletonX, y - 6, skeletonWidth, 12, 4);
4833
+ ctx.fill();
4834
+ ctx.restore();
4835
+ }
4836
+ continue;
4837
+ }
4838
+ const value = getTableValue(row.record, column.dataIndex, column.code ?? column.key);
4839
+ const content2 = column.canvasRender ? column.canvasRender(value, row.record, row.sourceIndex, { row, rowIndex: index, column }) : { text: value == null ? "" : String(value) };
4840
+ if (!content2?.text) continue;
4841
+ const available = Math.max(0, cellWidth - (content2.background ? 32 : 16));
4842
+ let text = content2.text;
4821
4843
  if (ctx.measureText(text).width > available) {
4822
4844
  let lo = 0, hi = text.length;
4823
4845
  while (lo < hi) {
@@ -4828,16 +4850,16 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
4828
4850
  text = text.slice(0, lo) + "\u2026";
4829
4851
  }
4830
4852
  const textWidth = ctx.measureText(text).width;
4831
- const total = textWidth + (content.background ? 16 : 0);
4853
+ const total = textWidth + (content2.background ? 16 : 0);
4832
4854
  const tx = column.align === "right" ? x + cellWidth - total - 8 : column.align === "center" ? x + (cellWidth - total) / 2 : x + 8;
4833
- if (content.background) {
4834
- ctx.fillStyle = content.background;
4855
+ if (content2.background) {
4856
+ ctx.fillStyle = content2.background;
4835
4857
  ctx.beginPath();
4836
4858
  ctx.roundRect(tx, y - 12, total, 24, 4);
4837
4859
  ctx.fill();
4838
4860
  }
4839
- ctx.fillStyle = content.color ?? foreground;
4840
- ctx.fillText(text, tx + (content.background ? 8 : 0), y);
4861
+ ctx.fillStyle = content2.color ?? foreground;
4862
+ ctx.fillText(text, tx + (content2.background ? 8 : 0), y);
4841
4863
  }
4842
4864
  ctx.restore();
4843
4865
  }
@@ -4848,6 +4870,8 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
4848
4870
  scroller.addEventListener("scroll", schedule, { passive: true });
4849
4871
  const resize = new ResizeObserver(schedule);
4850
4872
  resize.observe(scroller);
4873
+ const content = new MutationObserver(schedule);
4874
+ content.observe(scroller, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-canvas-row-index", "data-canvas-dom-ready", "data-column-key"] });
4851
4875
  const theme = new MutationObserver(schedule);
4852
4876
  theme.observe(document.documentElement, { attributes: true });
4853
4877
  window.addEventListener("resize", schedule);
@@ -4855,6 +4879,7 @@ function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHe
4855
4879
  return () => {
4856
4880
  cancelAnimationFrame(frame);
4857
4881
  resize.disconnect();
4882
+ content.disconnect();
4858
4883
  theme.disconnect();
4859
4884
  scroller.removeEventListener("scroll", schedule);
4860
4885
  window.removeEventListener("resize", schedule);
@@ -7404,6 +7429,7 @@ var TableBodyRow = memo(function TableBodyRow2({
7404
7429
  return /* @__PURE__ */ jsx23(
7405
7430
  "tr",
7406
7431
  {
7432
+ "data-canvas-row-index": canvas ? rowIndex : void 0,
7407
7433
  className: `sia-table__row${striped && rowIndex % 2 === 1 ? " sia-table__row--striped" : ""} ${className}`.trim(),
7408
7434
  style: { height: rowHeight },
7409
7435
  onClick,
@@ -7429,6 +7455,7 @@ var TableBodyRow = memo(function TableBodyRow2({
7429
7455
  "td",
7430
7456
  {
7431
7457
  "data-column-key": column.key,
7458
+ "data-canvas-dom-ready": canvas && (pluginCellProps.content !== void 0 || !column.canvasRender && column.render) ? "true" : void 0,
7432
7459
  "aria-label": canvas ? column.canvasRender?.(value, row.record, row.sourceIndex, { row, rowIndex, column })?.text ?? (value == null ? "" : String(value)) : void 0,
7433
7460
  rowSpan: pluginCellProps.rowSpan,
7434
7461
  colSpan: pluginCellProps.colSpan,
@@ -142,7 +142,7 @@ interface DateRangePickerProps extends Omit<DatePickerProps, "value" | "defaultV
142
142
  /** 值发生变化时调用;参数为新值及类型声明中列出的关联信息。 */
143
143
  onChange?: (value: readonly [string, string]) => void;
144
144
  }
145
- /** 日期范围选择;纯日期按两次点击组成范围,带时间时使用单面板分步设置起止值并确认提交。 */
145
+ /** 日期范围选择;纯日期按两次点击组成范围,带时间时使用单面板分步设置起止值并确认提交,活动底线随编辑端点平滑移动。 */
146
146
  declare function DateRangePicker({ value, defaultValue, placeholder, placeholderMode, separator, presets, maxRangeDays, allowEmpty, endpointDisabled, size: sizeProp, status, allowClear, needConfirm, showTime, showToday, open, defaultOpen, suffixIcon, minDate, maxDate, disabledDate, disabled, className, onCalendarChange, onChange, onOpenChange, formatValue, renderExtraFooter, ...props }: DateRangePickerProps): react.JSX.Element;
147
147
  /** 日期选择组件。 */
148
148
  declare function DatePicker({ value, defaultValue, picker, size: sizeProp, status, allowClear, multiple, needConfirm, showTime, showToday, open, defaultOpen, suffixIcon, minDate, maxDate, presets, disabledDate, disabled, className, onChange, onOpenChange, placeholder, placeholderMode, formatValue, renderExtraFooter, ...props }: DatePickerProps): react.JSX.Element;
@@ -142,7 +142,7 @@ interface DateRangePickerProps extends Omit<DatePickerProps, "value" | "defaultV
142
142
  /** 值发生变化时调用;参数为新值及类型声明中列出的关联信息。 */
143
143
  onChange?: (value: readonly [string, string]) => void;
144
144
  }
145
- /** 日期范围选择;纯日期按两次点击组成范围,带时间时使用单面板分步设置起止值并确认提交。 */
145
+ /** 日期范围选择;纯日期按两次点击组成范围,带时间时使用单面板分步设置起止值并确认提交,活动底线随编辑端点平滑移动。 */
146
146
  declare function DateRangePicker({ value, defaultValue, placeholder, placeholderMode, separator, presets, maxRangeDays, allowEmpty, endpointDisabled, size: sizeProp, status, allowClear, needConfirm, showTime, showToday, open, defaultOpen, suffixIcon, minDate, maxDate, disabledDate, disabled, className, onCalendarChange, onChange, onOpenChange, formatValue, renderExtraFooter, ...props }: DateRangePickerProps): react.JSX.Element;
147
147
  /** 日期选择组件。 */
148
148
  declare function DatePicker({ value, defaultValue, picker, size: sizeProp, status, allowClear, multiple, needConfirm, showTime, showToday, open, defaultOpen, suffixIcon, minDate, maxDate, presets, disabledDate, disabled, className, onChange, onOpenChange, placeholder, placeholderMode, formatValue, renderExtraFooter, ...props }: DatePickerProps): react.JSX.Element;
@@ -2005,6 +2005,24 @@ function DateRangePicker({
2005
2005
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
2006
2006
  const [draftValue, setDraftValue] = (0, import_react7.useState)(currentValue);
2007
2007
  const [activeIndex, setActiveIndex] = (0, import_react7.useState)(endpointDisabled[0] || currentValue[0] && !currentValue[1] ? 1 : 0);
2008
+ const indicatorRef = (0, import_react7.useRef)(null);
2009
+ (0, import_react7.useLayoutEffect)(() => {
2010
+ const field = rootRef.current?.querySelector(`[data-range-endpoint="${activeIndex}"]`);
2011
+ const indicator = indicatorRef.current;
2012
+ if (!field || !indicator) return;
2013
+ const alignIndicator = () => {
2014
+ indicator.style.transform = `translateX(${field.offsetLeft}px)`;
2015
+ indicator.style.width = `${field.offsetWidth}px`;
2016
+ };
2017
+ alignIndicator();
2018
+ const observer = new ResizeObserver(alignIndicator);
2019
+ const trigger = field.parentElement;
2020
+ if (trigger) {
2021
+ observer.observe(trigger);
2022
+ for (const child of trigger.children) if (child !== indicator) observer.observe(child);
2023
+ }
2024
+ return () => observer.disconnect();
2025
+ });
2008
2026
  const [confirmedIndex, setConfirmedIndex] = (0, import_react7.useState)(null);
2009
2027
  const [presetSelected, setPresetSelected] = (0, import_react7.useState)(false);
2010
2028
  const [hoverDate, setHoverDate] = (0, import_react7.useState)("");
@@ -2271,6 +2289,7 @@ function DateRangePicker({
2271
2289
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: `sia-picker-range-control__value${displayValue[1] ? "" : " is-placeholder"}`, children: displayValue[1] ? formatValue(displayValue[1]) : placeholder[1] }),
2272
2290
  endFloating.label
2273
2291
  ] }),
2292
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { ref: indicatorRef, className: "sia-picker-range-control__indicator", "aria-hidden": "true" }),
2274
2293
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sia-picker__icon", "aria-hidden": "true", children: suffixIcon ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { name: "calendar", size: 16 }) })
2275
2294
  ]
2276
2295
  }
@@ -1,4 +1,4 @@
1
- export { S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-2galnCvZ.cjs';
1
+ export { S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-CyfCT32j.cjs';
2
2
  import 'react';
3
3
  import './shared-Bx4B28Wh.cjs';
4
4
  import './Select-YJbT-MF1.cjs';
@@ -1,4 +1,4 @@
1
- export { S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-Dtj6XF9I.js';
1
+ export { S as SelectDateRange, i as SelectDateRangeProps, j as SelectDateRangeValue } from './select-date-range-B1ZWIHoe.js';
2
2
  import 'react';
3
3
  import './shared-Bx4B28Wh.js';
4
4
  import './Select-CCrPqULn.js';
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SelectDateRange
3
- } from "./chunk-QIXU7N4X.js";
3
+ } from "./chunk-E4RMSZOC.js";
4
4
  import "./chunk-NYJSSPIX.js";
5
5
  import "./chunk-XCVAVCIO.js";
6
6
  import "./chunk-IKAMZNCK.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sia.soul/sia-react-ui",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
4
4
  "description": "Sia Design components and tokens for React",
5
5
  "publishConfig": {
6
6
  "access": "public",