@leavepulse/ui 0.20.7 → 0.20.8

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.
@@ -25,6 +25,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
25
25
  function pillUnder(value, active) {
26
26
  return hovered.value ? hovered.value === value : active === value;
27
27
  }
28
+ function releaseFocusAfterPointer(event) {
29
+ const target = event.currentTarget;
30
+ if (target instanceof HTMLElement) target.blur();
31
+ }
28
32
  return (_ctx, _cache) => {
29
33
  return openBlock(), createBlock(unref(TabsRoot), {
30
34
  "model-value": __props.modelValue,
@@ -50,7 +54,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
50
54
  __props.accent ? "data-[state=active]:text-brand" : "data-[state=active]:text-ink",
51
55
  hovered.value === item.value ? "text-ink" : "text-muted"
52
56
  ]]),
53
- onPointerenter: ($event) => hovered.value = item.value
57
+ onPointerenter: ($event) => hovered.value = item.value,
58
+ onPointerup: releaseFocusAfterPointer
54
59
  }, {
55
60
  default: withCtx(() => [
56
61
  pillUnder(item.value, __props.modelValue) ? (openBlock(), createBlock(unref(Motion), {
@@ -20,13 +20,13 @@ type __VLS_Props = {
20
20
  /** Stretch the bar to full width with equal-share triggers. */
21
21
  block?: boolean;
22
22
  };
23
- declare var __VLS_48: {
23
+ declare var __VLS_49: {
24
24
  value: string;
25
- }, __VLS_50: {};
25
+ }, __VLS_51: {};
26
26
  type __VLS_Slots = {} & {
27
- panel?: (props: typeof __VLS_48) => any;
27
+ panel?: (props: typeof __VLS_49) => any;
28
28
  } & {
29
- default?: (props: typeof __VLS_50) => any;
29
+ default?: (props: typeof __VLS_51) => any;
30
30
  };
31
31
  declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
32
32
  "update:modelValue": (value: string) => any;
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpTabs-D7aTVPOb.js";
1
+ import { _ as _sfc_main } from "../chunks/LpTabs-Cefe_lys.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ import { _ as _50 } from "./chunks/LpStepper-5dFTrW21.js";
56
56
  import { _ as _51 } from "./chunks/LpSwitch-v6fnccSM.js";
57
57
  import { _ as _52 } from "./chunks/LpTable-pZmjnEti.js";
58
58
  import { _ as _53 } from "./chunks/LpTableOfContents-CjvxPMpU.js";
59
- import { _ as _54 } from "./chunks/LpTabs-D7aTVPOb.js";
59
+ import { _ as _54 } from "./chunks/LpTabs-Cefe_lys.js";
60
60
  import { _ as _55 } from "./chunks/LpTextarea-CRAkhemZ.js";
61
61
  import { p as presets, a as parseTheme, s as serializeTheme } from "./chunks/LpThemeSwitcher-B_kj0T2b.js";
62
62
  import { D, _ as _56, N, T, b, c, d, e, f, g, i, l, h, j, n, r, t, k, m, u, v } from "./chunks/LpThemeSwitcher-B_kj0T2b.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.20.7",
3
+ "version": "0.20.8",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -57,6 +57,25 @@ const panelLayoutTransition = computed(() =>
57
57
  function pillUnder(value: string, active?: string): boolean {
58
58
  return hovered.value ? hovered.value === value : active === value
59
59
  }
60
+
61
+ /*
62
+ * Drop focus after a mouse pick.
63
+ *
64
+ * Tabs implement the ARIA roving-focus pattern: while a trigger holds focus,
65
+ * ←/→ move between tabs. That is correct for keyboard users, but a *click*
66
+ * also leaves focus on the trigger — so afterwards the arrow keys silently
67
+ * belong to the tab strip, and any arrow-key handling the surrounding app has
68
+ * (walking a grid, moving a selection) appears to be broken until the user
69
+ * clicks somewhere else.
70
+ *
71
+ * Blurring on pointerup restores the arrows to the page without touching the
72
+ * keyboard path: Tab/←/→ navigation still focuses triggers and still works,
73
+ * because those never fire a pointer event.
74
+ */
75
+ function releaseFocusAfterPointer(event: PointerEvent) {
76
+ const target = event.currentTarget
77
+ if (target instanceof HTMLElement) target.blur()
78
+ }
60
79
  </script>
61
80
 
62
81
  <template>
@@ -85,6 +104,7 @@ function pillUnder(value: string, active?: string): boolean {
85
104
  hovered === item.value ? 'text-ink' : 'text-muted',
86
105
  ]"
87
106
  @pointerenter="hovered = item.value"
107
+ @pointerup="releaseFocusAfterPointer"
88
108
  >
89
109
  <!-- Active marker: a bottom bar in "underline", a filled pill otherwise.
90
110
  Both slide between tabs via the shared motion layoutId. -->