@sia.soul/sia-react-ui 0.1.4 → 0.1.5

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/index.js CHANGED
@@ -1259,7 +1259,7 @@ function openDrawer(config) {
1259
1259
  let currentOpen = true;
1260
1260
  let destroyed = false;
1261
1261
  let cleanupTimer;
1262
- function cleanup() {
1262
+ function cleanup2() {
1263
1263
  if (destroyed) return;
1264
1264
  destroyed = true;
1265
1265
  if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
@@ -1271,7 +1271,7 @@ function openDrawer(config) {
1271
1271
  if (destroyed || !currentOpen) return;
1272
1272
  currentOpen = false;
1273
1273
  render();
1274
- cleanupTimer = window.setTimeout(cleanup, DRAWER_MOTION_DURATION + 100);
1274
+ cleanupTimer = window.setTimeout(cleanup2, DRAWER_MOTION_DURATION + 100);
1275
1275
  }
1276
1276
  function render() {
1277
1277
  root.render(/* @__PURE__ */ jsx8(
@@ -1286,7 +1286,7 @@ function openDrawer(config) {
1286
1286
  afterOpen: () => currentConfig.afterOpen?.(),
1287
1287
  afterClose: () => {
1288
1288
  currentConfig.afterClose?.();
1289
- cleanup();
1289
+ cleanup2();
1290
1290
  }
1291
1291
  }
1292
1292
  ));
@@ -3806,7 +3806,7 @@ function Markdown({ content, emptyText = "\u6682\u65E0 Markdown \u5185\u5BB9", r
3806
3806
  });
3807
3807
  return () => {
3808
3808
  cancelled = true;
3809
- cleanups.forEach((cleanup) => cleanup());
3809
+ cleanups.forEach((cleanup2) => cleanup2());
3810
3810
  };
3811
3811
  }, [html, imagePreview, resolveImageSrc]);
3812
3812
  function openImagePreview(target) {
@@ -4398,6 +4398,68 @@ function Treemap({
4398
4398
  );
4399
4399
  }
4400
4400
 
4401
+ // src/components/useScrollbarProximity.ts
4402
+ import { useEffect as useEffect11 } from "react";
4403
+ var users = 0;
4404
+ var cleanup;
4405
+ function useScrollbarProximity() {
4406
+ useEffect11(() => {
4407
+ if (users++ === 0) {
4408
+ let frame = 0;
4409
+ let x = -Infinity;
4410
+ let y = -Infinity;
4411
+ const nearby = /* @__PURE__ */ new Set();
4412
+ const clear = () => {
4413
+ nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
4414
+ nearby.clear();
4415
+ };
4416
+ const update = () => {
4417
+ frame = 0;
4418
+ const next = /* @__PURE__ */ new Set();
4419
+ document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
4420
+ const rect = track.getBoundingClientRect();
4421
+ const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
4422
+ if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
4423
+ next.add(track);
4424
+ if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
4425
+ }
4426
+ });
4427
+ nearby.forEach((track) => {
4428
+ if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
4429
+ });
4430
+ nearby.clear();
4431
+ next.forEach((track) => nearby.add(track));
4432
+ };
4433
+ const move = (event) => {
4434
+ if (event.pointerType === "touch") return;
4435
+ x = event.clientX;
4436
+ y = event.clientY;
4437
+ if (!frame) frame = requestAnimationFrame(update);
4438
+ };
4439
+ const leave = () => {
4440
+ x = y = -Infinity;
4441
+ clear();
4442
+ };
4443
+ document.addEventListener("pointermove", move, { passive: true });
4444
+ document.documentElement.addEventListener("pointerleave", leave);
4445
+ window.addEventListener("blur", leave);
4446
+ cleanup = () => {
4447
+ if (frame) cancelAnimationFrame(frame);
4448
+ document.removeEventListener("pointermove", move);
4449
+ document.documentElement.removeEventListener("pointerleave", leave);
4450
+ window.removeEventListener("blur", leave);
4451
+ clear();
4452
+ };
4453
+ }
4454
+ return () => {
4455
+ if (--users === 0) {
4456
+ cleanup?.();
4457
+ cleanup = void 0;
4458
+ }
4459
+ };
4460
+ }, []);
4461
+ }
4462
+
4401
4463
  // src/components/Table/TableCellContent.tsx
4402
4464
  import { useLayoutEffect, useRef as useRef12, useState as useState15 } from "react";
4403
4465
  import { jsx as jsx19 } from "react/jsx-runtime";
@@ -4419,10 +4481,10 @@ function TableCellContent({ children, ellipsis, title }) {
4419
4481
  }
4420
4482
 
4421
4483
  // src/components/Table/Table.tsx
4422
- import { Fragment as Fragment7, forwardRef as forwardRef5, memo, useCallback as useCallback2, useEffect as useEffect12, useImperativeHandle, useMemo as useMemo9, useRef as useRef14, useState as useState17 } from "react";
4484
+ import { Fragment as Fragment7, forwardRef as forwardRef5, memo, useCallback as useCallback2, useEffect as useEffect13, useImperativeHandle, useMemo as useMemo9, useRef as useRef14, useState as useState17 } from "react";
4423
4485
 
4424
4486
  // src/components/Table/plugins.tsx
4425
- import { isValidElement as isValidElement3, useEffect as useEffect11, useRef as useRef13, useState as useState16 } from "react";
4487
+ import { isValidElement as isValidElement3, useEffect as useEffect12, useRef as useRef13, useState as useState16 } from "react";
4426
4488
 
4427
4489
  // src/components/Table/utils.ts
4428
4490
  var AUTO_WIDTH_COLUMN_KEYS = /* @__PURE__ */ new Set(["action", "actions", "operation", "operations"]);
@@ -5172,7 +5234,7 @@ function TableFilterControl({
5172
5234
  const [open, setOpen] = useState16(false);
5173
5235
  const [draft, setDraft] = useState16(value);
5174
5236
  const label = getColumnLabel(column);
5175
- useEffect11(() => {
5237
+ useEffect12(() => {
5176
5238
  if (open) setDraft(value);
5177
5239
  }, [open, value]);
5178
5240
  const apply = (nextValue) => {
@@ -5445,7 +5507,7 @@ function EditableTableCell({
5445
5507
  const savingRef = useRef13(false);
5446
5508
  const saveRef = useRef13(async () => {
5447
5509
  });
5448
- useEffect11(() => {
5510
+ useEffect12(() => {
5449
5511
  if (!active) return;
5450
5512
  editValueRef.current = value;
5451
5513
  setEditValue(value);
@@ -5476,7 +5538,7 @@ function EditableTableCell({
5476
5538
  }
5477
5539
  }
5478
5540
  saveRef.current = save;
5479
- useEffect11(() => {
5541
+ useEffect12(() => {
5480
5542
  if (!active || config.type === "select" || config.type === "custom") return;
5481
5543
  const handleOutsidePointerDown = (event) => {
5482
5544
  const target = event.target;
@@ -5637,7 +5699,7 @@ function applyColumnSettingsToTree(columns, items) {
5637
5699
  function ColumnSettingPanel({ open, items, columns, onClose, onApply }) {
5638
5700
  const [draft, setDraft] = useState16(items);
5639
5701
  const dragIndex = useRef13(null);
5640
- useEffect11(() => {
5702
+ useEffect12(() => {
5641
5703
  if (open) setDraft(items);
5642
5704
  }, [items, open]);
5643
5705
  const labels = new Map(flattenTableColumns(columns).map((column) => [column.key, getColumnLabel(column)]));
@@ -5732,7 +5794,30 @@ function createColumnSettingPlugin(options = {}) {
5732
5794
  void save({ columns: currentItems(context), pageSize, version: 1 });
5733
5795
  }
5734
5796
  },
5735
- renderToolbarEnd: options.showButton === false ? void 0 : (context) => /* @__PURE__ */ jsx20(Button, { size: "small", variant: "text", className: "sia-table__toolbar-icon", icon: /* @__PURE__ */ jsx20(Icon, { name: "settings", size: 16 }), "aria-label": "\u6253\u5F00\u5217\u8BBE\u7F6E", title: "\u5217\u8BBE\u7F6E", onClick: () => context.setState((state) => ({ ...state, open: true })) }),
5797
+ renderToolbarEnd: options.showButton === false ? void 0 : (context) => {
5798
+ const exportApi = () => context.getPluginApi("export") ?? createExportPlugin().getApi({ ...context, state: void 0, setState: () => {
5799
+ } });
5800
+ const customItems = (options.menuItems ?? []).filter((item) => !(item.hidden === true || typeof item.hidden === "function" && item.hidden(context)));
5801
+ const items = [
5802
+ ...options.showExport === false ? [] : [
5803
+ { key: "builtin:export", label: "\u8868\u683C\u5BFC\u51FA", icon: /* @__PURE__ */ jsx20(Icon, { name: "download", size: 18 }), disabled: exportApi().getRows().length === 0 },
5804
+ { key: "builtin:divider", type: "divider" }
5805
+ ],
5806
+ { key: "builtin:columns", label: "\u5217\u8BBE\u7F6E", icon: /* @__PURE__ */ jsx20(Icon, { name: "settings", size: 18 }) },
5807
+ ...customItems.map((item) => ({
5808
+ key: "custom:" + item.key,
5809
+ label: item.label,
5810
+ icon: item.icon,
5811
+ danger: item.danger,
5812
+ disabled: item.disabled === true || typeof item.disabled === "function" && item.disabled(context)
5813
+ }))
5814
+ ];
5815
+ return /* @__PURE__ */ jsx20(Dropdown, { trigger: ["hover", "click"], placement: "bottomRight", popupClassName: "sia-table__settings-dropdown", menu: { items, onClick: ({ key }) => {
5816
+ if (key === "builtin:export") void exportApi().download();
5817
+ else if (key === "builtin:columns") context.setState((state) => ({ ...state, open: true }));
5818
+ else void customItems.find((item) => "custom:" + item.key === key)?.onClick?.(context);
5819
+ } }, children: /* @__PURE__ */ jsx20(Button, { size: "small", variant: "text", className: "sia-table__toolbar-icon", icon: /* @__PURE__ */ jsx20(Icon, { name: "settings", size: 16 }), "aria-label": "\u8868\u683C\u8BBE\u7F6E" }) });
5820
+ },
5736
5821
  renderOverlay: (context) => /* @__PURE__ */ jsx20(ColumnSettingPanel, { open: context.state.open, items: currentItems(context), columns: context.baseColumns, onClose: () => context.setState((state) => ({ ...state, open: false })), onApply: (items) => apply(items, context) }),
5737
5822
  getApi: (context) => ({ open: () => context.setState((state) => ({ ...state, open: true })), close: () => context.setState((state) => ({ ...state, open: false })), getSettings: () => currentItems(context), apply: (items) => apply(items, context) })
5738
5823
  };
@@ -6017,6 +6102,7 @@ function TableInner(props, ref) {
6017
6102
  tableHeight,
6018
6103
  size = "medium",
6019
6104
  bordered = true,
6105
+ toolbarBordered = false,
6020
6106
  striped = true,
6021
6107
  virtual,
6022
6108
  virtualThreshold = 100,
@@ -6036,6 +6122,7 @@ function TableInner(props, ref) {
6036
6122
  const rootRef = useRef14(null);
6037
6123
  const scrollRef = useRef14(null);
6038
6124
  const tableRef = useRef14(null);
6125
+ useScrollbarProximity();
6039
6126
  const scrollbarDragRef = useRef14(null);
6040
6127
  const [internalLoading, setInternalLoading] = useState17(false);
6041
6128
  const [scrollTop, setScrollTop] = useState17(0);
@@ -6116,7 +6203,7 @@ function TableInner(props, ref) {
6116
6203
  });
6117
6204
  pluginApisRef.current = nextApis;
6118
6205
  contextsRef.current = contexts;
6119
- useEffect12(() => {
6206
+ useEffect13(() => {
6120
6207
  const activePlugins2 = new Map(sortedPlugins.map((plugin) => [plugin.id, plugin]));
6121
6208
  for (const [pluginId, mounted] of mountedPluginsRef.current) {
6122
6209
  if (activePlugins2.get(pluginId) === mounted.plugin) continue;
@@ -6128,7 +6215,7 @@ function TableInner(props, ref) {
6128
6215
  mountedPluginsRef.current.set(plugin.id, { plugin, cleanup: plugin.onMount(contextsRef.current.get(plugin.id)) });
6129
6216
  }
6130
6217
  }, [sortedPlugins]);
6131
- useEffect12(() => () => {
6218
+ useEffect13(() => () => {
6132
6219
  for (const mounted of mountedPluginsRef.current.values()) mounted.cleanup?.();
6133
6220
  mountedPluginsRef.current.clear();
6134
6221
  }, []);
@@ -6140,8 +6227,10 @@ function TableInner(props, ref) {
6140
6227
  if (element.scrollLeft > maxLeft) element.scrollLeft = maxLeft > 1 ? maxLeft : 0;
6141
6228
  const logicalScrollLeft = Math.min(element.scrollLeft, maxLeft);
6142
6229
  const maxTop = Math.max(0, element.scrollHeight - element.clientHeight);
6143
- const horizontalTrack = Math.max(0, element.clientWidth - 8);
6144
- const verticalTrack = Math.max(0, element.clientHeight - 8);
6230
+ root.dataset.overflowX = String(maxLeft > 1);
6231
+ root.dataset.overflowY = String(maxTop > 1);
6232
+ const horizontalTrack = root.querySelector(".sia-table__scrollbar--horizontal")?.clientWidth ?? 0;
6233
+ const verticalTrack = root.querySelector(".sia-table__scrollbar--vertical")?.clientHeight ?? 0;
6145
6234
  const horizontalThumb = maxLeft > 1 ? Math.min(horizontalTrack, Math.max(36, horizontalTrack * element.clientWidth / horizontalContentWidth)) : 0;
6146
6235
  const verticalThumb = maxTop > 1 ? Math.min(verticalTrack, Math.max(36, verticalTrack * element.clientHeight / element.scrollHeight)) : 0;
6147
6236
  const horizontalPosition = maxLeft > 0 ? logicalScrollLeft / maxLeft * Math.max(0, horizontalTrack - horizontalThumb) : 0;
@@ -6166,7 +6255,7 @@ function TableInner(props, ref) {
6166
6255
  root.style.setProperty("--sia-table-scrollbar-y-size", `${verticalThumb}px`);
6167
6256
  root.style.setProperty("--sia-table-scrollbar-y-position", `${verticalPosition}px`);
6168
6257
  }, []);
6169
- useEffect12(() => {
6258
+ useEffect13(() => {
6170
6259
  const element = scrollRef.current;
6171
6260
  if (!element || typeof ResizeObserver === "undefined") return;
6172
6261
  const observer = new ResizeObserver(() => {
@@ -6179,13 +6268,13 @@ function TableInner(props, ref) {
6179
6268
  updateScrollMetrics();
6180
6269
  return () => observer.disconnect();
6181
6270
  }, [updateScrollMetrics]);
6182
- useEffect12(() => {
6271
+ useEffect13(() => {
6183
6272
  updateScrollMetrics();
6184
6273
  });
6185
6274
  const orderedColumns = useMemo9(() => sortTableColumnsByFixed(pipeline.columns), [pipeline.columns]);
6186
6275
  const leafColumns = useMemo9(() => flattenTableColumns(orderedColumns), [orderedColumns]);
6187
6276
  const headerRows = useMemo9(() => buildHeaderRows(orderedColumns), [orderedColumns]);
6188
- useEffect12(() => {
6277
+ useEffect13(() => {
6189
6278
  const autoWidthColumns = leafColumns.filter((column) => column.autoWidth && resizedWidths[column.key] === void 0);
6190
6279
  const root = rootRef.current;
6191
6280
  if (!root || autoWidthColumns.length === 0) return;
@@ -6282,16 +6371,26 @@ function TableInner(props, ref) {
6282
6371
  if (shouldVirtualize) setScrollTop(element.scrollTop);
6283
6372
  updateScrollMetrics();
6284
6373
  }, [shouldVirtualize, updateScrollMetrics]);
6285
- const handleScrollbarPointerDown = useCallback2((axis, event) => {
6374
+ const handleScrollbarPointerDown = useCallback2((axis, event, track = event.currentTarget) => {
6286
6375
  const element = scrollRef.current;
6287
- const track = event.currentTarget.parentElement;
6288
- if (!element || !track) return;
6376
+ const thumb = track.firstElementChild;
6377
+ if (!element || !thumb || event.button !== 0) return;
6289
6378
  event.preventDefault();
6290
6379
  event.stopPropagation();
6291
- event.currentTarget.setPointerCapture(event.pointerId);
6380
+ track.setPointerCapture(event.pointerId);
6292
6381
  const trackLength = axis === "x" ? track.clientWidth : track.clientHeight;
6293
- const thumbLength = axis === "x" ? event.currentTarget.offsetWidth : event.currentTarget.offsetHeight;
6382
+ const thumbLength = axis === "x" ? thumb.offsetWidth : thumb.offsetHeight;
6294
6383
  const maxScroll = axis === "x" ? getTableHorizontalMetrics(element, tableRef.current).maxLeft : element.scrollHeight - element.clientHeight;
6384
+ const thumbRect = thumb.getBoundingClientRect();
6385
+ const coordinate = axis === "x" ? event.clientX : event.clientY;
6386
+ const thumbStart = axis === "x" ? thumbRect.left : thumbRect.top;
6387
+ if (coordinate < thumbStart || coordinate > thumbStart + thumbLength) {
6388
+ const trackRect = track.getBoundingClientRect();
6389
+ const trackStart = axis === "x" ? trackRect.left : trackRect.top;
6390
+ const ratio = Math.max(0, Math.min(1, (coordinate - trackStart - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
6391
+ if (axis === "x") element.scrollLeft = ratio * maxScroll;
6392
+ else element.scrollTop = ratio * maxScroll;
6393
+ }
6295
6394
  scrollbarDragRef.current = {
6296
6395
  axis,
6297
6396
  pointerId: event.pointerId,
@@ -6384,6 +6483,16 @@ function TableInner(props, ref) {
6384
6483
  };
6385
6484
  }, {});
6386
6485
  }
6486
+ function scrollbarAtPoint(event) {
6487
+ const tracks = rootRef.current?.querySelectorAll(".sia-table__scrollbar");
6488
+ for (const track of tracks ?? []) {
6489
+ if (track.closest(".sia-table") !== rootRef.current) continue;
6490
+ const rect = track.getBoundingClientRect();
6491
+ if (rect.width > 0 && rect.height > 0 && event.clientX >= rect.left && event.clientX < rect.right && event.clientY >= rect.top && event.clientY < rect.bottom) {
6492
+ return { track, axis: track.classList.contains("sia-table__scrollbar--vertical") ? "y" : "x" };
6493
+ }
6494
+ }
6495
+ }
6387
6496
  function renderSummaryRow(summary) {
6388
6497
  let labelRendered = false;
6389
6498
  return /* @__PURE__ */ jsx21("tr", { className: `sia-table__summary-row ${summary.className ?? ""}`.trim(), children: leafColumns.map((column) => {
@@ -6399,13 +6508,51 @@ function TableInner(props, ref) {
6399
6508
  "div",
6400
6509
  {
6401
6510
  ref: rootRef,
6402
- className: `sia-table sia-table--${size}${bordered ? " sia-table--bordered" : ""} ${className}`.trim(),
6511
+ className: `sia-table sia-table--${size}${bordered ? " sia-table--bordered" : ""}${hasToolbar && !toolbarBordered ? " sia-table--borderless-toolbar" : ""} ${className}`.trim(),
6403
6512
  style: rootStyle,
6404
6513
  "data-has-fixed-left": left > 0,
6405
6514
  "data-has-fixed-right": right > 0,
6406
6515
  "data-scrolled-left": "false",
6407
6516
  "data-scrolled-right": "true",
6408
6517
  ...htmlProps,
6518
+ onPointerDownCapture: (event) => {
6519
+ htmlProps.onPointerDownCapture?.(event);
6520
+ if (event.defaultPrevented || loading || internalLoading) return;
6521
+ const hit = scrollbarAtPoint(event);
6522
+ if (hit) handleScrollbarPointerDown(hit.axis, event, hit.track);
6523
+ },
6524
+ onPointerMoveCapture: (event) => {
6525
+ htmlProps.onPointerMoveCapture?.(event);
6526
+ const hit = scrollbarAtPoint(event);
6527
+ rootRef.current?.querySelectorAll(".sia-table__scrollbar").forEach((track) => {
6528
+ const hovered = track === hit?.track;
6529
+ if (hovered !== track.hasAttribute("data-pointer-hover")) track.toggleAttribute("data-pointer-hover", hovered);
6530
+ });
6531
+ if (hit || scrollbarDragRef.current) {
6532
+ handleScrollbarPointerMove(event);
6533
+ event.stopPropagation();
6534
+ }
6535
+ },
6536
+ onPointerLeave: (event) => {
6537
+ htmlProps.onPointerLeave?.(event);
6538
+ rootRef.current?.querySelectorAll("[data-pointer-hover]").forEach((track) => track.removeAttribute("data-pointer-hover"));
6539
+ },
6540
+ onClickCapture: (event) => {
6541
+ if (scrollbarAtPoint(event)) {
6542
+ event.preventDefault();
6543
+ event.stopPropagation();
6544
+ return;
6545
+ }
6546
+ htmlProps.onClickCapture?.(event);
6547
+ },
6548
+ onDoubleClickCapture: (event) => {
6549
+ if (scrollbarAtPoint(event)) {
6550
+ event.preventDefault();
6551
+ event.stopPropagation();
6552
+ return;
6553
+ }
6554
+ htmlProps.onDoubleClickCapture?.(event);
6555
+ },
6409
6556
  children: [
6410
6557
  hasToolbar ? /* @__PURE__ */ jsxs20("div", { className: "sia-table__toolbar", children: [
6411
6558
  /* @__PURE__ */ jsx21("div", { children: toolbarStart }),
@@ -6498,26 +6645,34 @@ function TableInner(props, ref) {
6498
6645
  summaries.length > 0 ? /* @__PURE__ */ jsx21("tfoot", { className: "sia-table__summary", children: summaries.map(renderSummaryRow) }) : null
6499
6646
  ] }) }),
6500
6647
  pipeline.rows.length === 0 ? /* @__PURE__ */ jsx21("div", { className: "sia-table__empty", role: "status", children: emptyText }) : null,
6501
- /* @__PURE__ */ jsx21("div", { className: "sia-scrollbar-track sia-table__scrollbar sia-table__scrollbar--horizontal", "aria-hidden": "true", children: /* @__PURE__ */ jsx21(
6648
+ /* @__PURE__ */ jsx21(
6502
6649
  "div",
6503
6650
  {
6504
- className: "sia-table__scrollbar-thumb",
6651
+ className: "sia-scrollbar-track sia-table__scrollbar sia-table__scrollbar--horizontal",
6652
+ "aria-hidden": "true",
6505
6653
  onPointerDown: (event) => handleScrollbarPointerDown("x", event),
6654
+ onClick: (event) => event.stopPropagation(),
6655
+ onDoubleClick: (event) => event.stopPropagation(),
6506
6656
  onPointerMove: handleScrollbarPointerMove,
6507
6657
  onPointerUp: handleScrollbarPointerEnd,
6508
- onPointerCancel: handleScrollbarPointerEnd
6658
+ onPointerCancel: handleScrollbarPointerEnd,
6659
+ children: /* @__PURE__ */ jsx21("div", { className: "sia-table__scrollbar-thumb" })
6509
6660
  }
6510
- ) }),
6511
- /* @__PURE__ */ jsx21("div", { className: "sia-scrollbar-track sia-table__scrollbar sia-table__scrollbar--vertical", "aria-hidden": "true", children: /* @__PURE__ */ jsx21(
6661
+ ),
6662
+ /* @__PURE__ */ jsx21(
6512
6663
  "div",
6513
6664
  {
6514
- className: "sia-table__scrollbar-thumb",
6665
+ className: "sia-scrollbar-track sia-table__scrollbar sia-table__scrollbar--vertical",
6666
+ "aria-hidden": "true",
6515
6667
  onPointerDown: (event) => handleScrollbarPointerDown("y", event),
6668
+ onClick: (event) => event.stopPropagation(),
6669
+ onDoubleClick: (event) => event.stopPropagation(),
6516
6670
  onPointerMove: handleScrollbarPointerMove,
6517
6671
  onPointerUp: handleScrollbarPointerEnd,
6518
- onPointerCancel: handleScrollbarPointerEnd
6672
+ onPointerCancel: handleScrollbarPointerEnd,
6673
+ children: /* @__PURE__ */ jsx21("div", { className: "sia-table__scrollbar-thumb" })
6519
6674
  }
6520
- ) })
6675
+ )
6521
6676
  ] }),
6522
6677
  footers.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "sia-table__footer", children: footers }) : null,
6523
6678
  loading || internalLoading ? /* @__PURE__ */ jsxs20("div", { className: "sia-table__loading", role: "status", children: [
@@ -6571,7 +6726,7 @@ var ThemeSwitch = forwardRef6(function ThemeSwitch2({
6571
6726
  });
6572
6727
 
6573
6728
  // src/components/FloatingScrollbarProvider.tsx
6574
- import { useEffect as useEffect13 } from "react";
6729
+ import { useEffect as useEffect14 } from "react";
6575
6730
  var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
6576
6731
  var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
6577
6732
  function isRootScroller(target) {
@@ -6634,7 +6789,8 @@ function createTrack(axis) {
6634
6789
  return { track, thumb };
6635
6790
  }
6636
6791
  function FloatingScrollbarProvider({ disabled = false }) {
6637
- useEffect13(() => {
6792
+ useScrollbarProximity();
6793
+ useEffect14(() => {
6638
6794
  if (disabled) return;
6639
6795
  const layer = document.createElement("div");
6640
6796
  layer.className = "sia-floating-scrollbar-layer";
@@ -6664,7 +6820,7 @@ function FloatingScrollbarProvider({ disabled = false }) {
6664
6820
  const hasHorizontal = canScroll(target, "horizontal");
6665
6821
  const hasVertical = canScroll(target, "vertical");
6666
6822
  const rect = visibleRect(target);
6667
- const thickness = 8;
6823
+ const thickness = 10;
6668
6824
  horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
6669
6825
  verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
6670
6826
  if (!horizontalTrack.hidden) {
@@ -6903,7 +7059,7 @@ function applySiaTheme(mode, target = document.documentElement) {
6903
7059
  }
6904
7060
 
6905
7061
  // src/components/SelectionPanel.tsx
6906
- import { useEffect as useEffect14, useId as useId7, useMemo as useMemo10, useRef as useRef15, useState as useState18 } from "react";
7062
+ import { useEffect as useEffect15, useId as useId7, useMemo as useMemo10, useRef as useRef15, useState as useState18 } from "react";
6907
7063
  import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
6908
7064
  function SelectionPanel({
6909
7065
  options,
@@ -6964,7 +7120,7 @@ function SelectionPanel({
6964
7120
  const virtual = filtered.length > 100;
6965
7121
  const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
6966
7122
  const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
6967
- useEffect14(() => {
7123
+ useEffect15(() => {
6968
7124
  setScrollTop(0);
6969
7125
  if (listRef.current) listRef.current.scrollTop = 0;
6970
7126
  setActive(void 0);
@@ -7074,7 +7230,7 @@ function SelectionPanel({
7074
7230
  }
7075
7231
 
7076
7232
  // src/components/InputSelect.tsx
7077
- import { forwardRef as forwardRef7, useEffect as useEffect15, useRef as useRef16, useState as useState19 } from "react";
7233
+ import { forwardRef as forwardRef7, useEffect as useEffect16, useRef as useRef16, useState as useState19 } from "react";
7078
7234
  import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
7079
7235
  var InputSelect = forwardRef7(function InputSelect2({
7080
7236
  options,
@@ -7106,7 +7262,7 @@ var InputSelect = forwardRef7(function InputSelect2({
7106
7262
  const values = current == null ? [] : Array.isArray(current) ? current : [current];
7107
7263
  const text = values.map((item) => displayField === "label" ? String(options.find((option) => option.optionType !== "divider" && option.value === item)?.label ?? item) : String(item)).join(",");
7108
7264
  const [draft, setDraft] = useState19(text);
7109
- useEffect15(() => {
7265
+ useEffect16(() => {
7110
7266
  setDraft(text);
7111
7267
  }, [text, current]);
7112
7268
  const [open, setOpen] = useState19(false);
@@ -7136,7 +7292,7 @@ var InputSelect = forwardRef7(function InputSelect2({
7136
7292
  inputRef.current?.focus();
7137
7293
  }
7138
7294
  }
7139
- useEffect15(() => {
7295
+ useEffect16(() => {
7140
7296
  if (!open) return;
7141
7297
  const outside = (event) => {
7142
7298
  if (!rootRef.current?.contains(event.target) && !popupRef.current?.contains(event.target)) changeOpen(false);
@@ -7144,7 +7300,7 @@ var InputSelect = forwardRef7(function InputSelect2({
7144
7300
  document.addEventListener("pointerdown", outside);
7145
7301
  return () => document.removeEventListener("pointerdown", outside);
7146
7302
  }, [open, onOpenChange]);
7147
- useEffect15(() => {
7303
+ useEffect16(() => {
7148
7304
  if (disabled || loading) {
7149
7305
  changeOpen(false);
7150
7306
  setModalOpen(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sia.soul/sia-react-ui",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Sia Design components and tokens for React",
5
5
  "publishConfig": {
6
6
  "access": "public",