@signal9/era-ui 1.5.1 → 1.7.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.
@@ -12,13 +12,16 @@
12
12
  } = $props();
13
13
  </script>
14
14
 
15
- <!-- data-pane-control carves this out of the drag zone so it clicks, not drags. -->
15
+ <!-- No data-pane-control: the button stays inside the handle's drag zone, so a
16
+ press-and-drag moves the pane (handy for grabbing a tiny pane by its
17
+ corner). A clean click still closes — neodrag only starts a drag on pointer
18
+ movement, and it suppresses the trailing click after an actual drag, so a
19
+ stationary click fires immediately with no delay. -->
16
20
  <Button
17
21
  bind:ref
18
22
  icon
19
23
  size="icon"
20
24
  tone="destructive"
21
- data-pane-control
22
25
  aria-label="Close"
23
26
  class={className}
24
27
  {...restProps}
@@ -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.7.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev --host",
6
6
  "build": "vite build && npm run prepack",