@signal9/era-ui 1.5.1 → 1.6.0

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.
@@ -6,14 +6,15 @@
6
6
  let { ref = $bindable(null), class: className, ...restProps }: TabsPrimitive.ListProps = $props();
7
7
 
8
8
  // When the pane is too narrow to fit every tab, the strip scrolls (min-w-0 +
9
- // overflow-x-auto — chromeless via scrollbar-none; wheel/touch work natively).
9
+ // overflow-x-auto — chromeless via scrollbar-none; touch pans natively).
10
10
  // data-pane-control carves it out of the pane's drag zone so a sideways drag
11
11
  // scrolls the tabs instead of moving the pane.
12
12
  //
13
13
  // Mouse drag-to-scroll: grab anywhere in the strip and slide. A small
14
14
  // threshold tells a scroll-drag from a tab click; once we've dragged, the
15
15
  // trailing click is swallowed (capture phase) so a tab isn't toggled. Touch
16
- // and pen fall through to native panning.
16
+ // and pen fall through to native panning. A wheel handler (below) maps the
17
+ // vertical mouse wheel onto horizontal scroll while hovering the strip.
17
18
  let startX = 0;
18
19
  let startScroll = 0;
19
20
  let dragging = false;
@@ -43,8 +44,13 @@
43
44
  if (ref?.hasPointerCapture(e.pointerId)) ref.releasePointerCapture(e.pointerId);
44
45
  }
45
46
 
46
- // Swallow the click that follows a scroll-drag so the tab under the cursor
47
- // isn't selected. Capture phase, so it beats the trigger's own handler.
47
+ // Two listeners that need non-default registration (capture / non-passive),
48
+ // so they're added imperatively rather than as element props:
49
+ // - click (capture): swallow the click that follows a scroll-drag so the
50
+ // tab under the cursor isn't selected — beats the trigger's own handler.
51
+ // - wheel (non-passive): translate a vertical mouse wheel into horizontal
52
+ // scroll while hovering the strip, and only consume the event when the
53
+ // strip can actually move that way (otherwise the page scrolls as usual).
48
54
  $effect(() => {
49
55
  const node = ref;
50
56
  if (!node) return;
@@ -55,8 +61,22 @@
55
61
  dragged = false;
56
62
  }
57
63
  };
64
+ const onWheel = (e: WheelEvent) => {
65
+ const max = node.scrollWidth - node.clientWidth;
66
+ if (max <= 0) return;
67
+ const delta = Math.abs(e.deltaY) >= Math.abs(e.deltaX) ? e.deltaY : e.deltaX;
68
+ if (delta === 0) return;
69
+ const next = Math.max(0, Math.min(max, node.scrollLeft + delta));
70
+ if (next === node.scrollLeft) return; // at an edge going further out — let it bubble
71
+ node.scrollLeft = next;
72
+ e.preventDefault();
73
+ };
58
74
  node.addEventListener('click', swallow, true);
59
- return () => node.removeEventListener('click', swallow, true);
75
+ node.addEventListener('wheel', onWheel, { passive: false });
76
+ return () => {
77
+ node.removeEventListener('click', swallow, true);
78
+ node.removeEventListener('wheel', onWheel);
79
+ };
60
80
  });
61
81
  </script>
62
82
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signal9/era-ui",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev --host",
6
6
  "build": "vite build && npm run prepack",