@leavepulse/ui 0.73.4 → 0.73.6

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.
@@ -5,34 +5,34 @@
5
5
  * pane from its right edge as it grows. Animating the columns themselves made
6
6
  * every line of the list and the pane re-wrap on every frame.
7
7
  */
8
- .lp-cmd-dialog[data-v-8d42f8db] {
8
+ .lp-cmd-dialog[data-v-2880ef37] {
9
9
  --lp-cmd-list: min(92vw, 40rem);
10
10
  --lp-cmd-pane: max(0px, min(26rem, 96vw - var(--lp-cmd-list)));
11
11
  width: var(--lp-cmd-list);
12
12
  }
13
- .lp-cmd-split[data-v-8d42f8db] {
13
+ .lp-cmd-split[data-v-2880ef37] {
14
14
  transition:
15
15
  width 300ms var(--ease-emphasized, ease),
16
16
  min-height 300ms var(--ease-emphasized, ease);
17
17
  }
18
18
  @media (min-width: 768px) {
19
- .lp-cmd-split .lp-cmd-list[data-v-8d42f8db] {
19
+ .lp-cmd-split .lp-cmd-list[data-v-2880ef37] {
20
20
  flex: 0 0 auto;
21
21
  /* the dialog's 1px border on each side */
22
22
  width: calc(var(--lp-cmd-list) - 2px);
23
23
  }
24
- .lp-cmd-dialog[data-pane="open"][data-v-8d42f8db] {
24
+ .lp-cmd-dialog[data-pane="open"][data-v-2880ef37] {
25
25
  width: calc(var(--lp-cmd-list) + var(--lp-cmd-pane));
26
26
  min-height: min(76vh, 36rem);
27
27
  }
28
28
  }
29
- .lp-cmd-pane[data-v-8d42f8db] {
29
+ .lp-cmd-pane[data-v-2880ef37] {
30
30
  width: var(--lp-cmd-pane);
31
31
  }
32
- .lp-cmd-dialog[data-editing] .lp-cmd-pane[data-v-8d42f8db] {
32
+ .lp-cmd-dialog[data-editing] .lp-cmd-pane[data-v-2880ef37] {
33
33
  width: 100%;
34
34
  }
35
- .lp-cmd-dialog[data-editing][data-v-8d42f8db] {
35
+ .lp-cmd-dialog[data-editing][data-v-2880ef37] {
36
36
  width: var(--lp-cmd-list);
37
37
  min-height: 0;
38
38
  }
@@ -40,43 +40,43 @@
40
40
  * The pane rides in from the right edge while the dialog opens up to it, and
41
41
  * leaves the same way, for as long as the dialog takes to close over it.
42
42
  */
43
- .lp-cmd-pane-enter-active[data-v-8d42f8db],
44
- .lp-cmd-pane-leave-active[data-v-8d42f8db] {
43
+ .lp-cmd-pane-enter-active[data-v-2880ef37],
44
+ .lp-cmd-pane-leave-active[data-v-2880ef37] {
45
45
  transition:
46
46
  transform 300ms var(--ease-emphasized, ease),
47
47
  opacity 300ms ease;
48
48
  }
49
- .lp-cmd-pane-enter-from[data-v-8d42f8db],
50
- .lp-cmd-pane-leave-to[data-v-8d42f8db] {
49
+ .lp-cmd-pane-enter-from[data-v-2880ef37],
50
+ .lp-cmd-pane-leave-to[data-v-2880ef37] {
51
51
  opacity: 0;
52
52
  transform: translateX(40%);
53
53
  }
54
- .lp-cmd-para[data-v-8d42f8db] {
54
+ .lp-cmd-para[data-v-2880ef37] {
55
55
  --rise: 4px;
56
56
  animation: rise-in 260ms ease-out both;
57
57
  }
58
58
  @media (prefers-reduced-motion: reduce) {
59
- .lp-cmd-split[data-v-8d42f8db],
60
- .lp-cmd-pane-enter-active[data-v-8d42f8db],
61
- .lp-cmd-pane-leave-active[data-v-8d42f8db] {
59
+ .lp-cmd-split[data-v-2880ef37],
60
+ .lp-cmd-pane-enter-active[data-v-2880ef37],
61
+ .lp-cmd-pane-leave-active[data-v-2880ef37] {
62
62
  transition: none;
63
63
  }
64
- .lp-cmd-para[data-v-8d42f8db] {
64
+ .lp-cmd-para[data-v-2880ef37] {
65
65
  animation: none;
66
66
  }
67
67
  }
68
- .lp-cmd-excerpt[data-v-8d42f8db] {
68
+ .lp-cmd-excerpt[data-v-2880ef37] {
69
69
  display: -webkit-box;
70
70
  -webkit-box-orient: vertical;
71
71
  overflow: hidden;
72
72
  }
73
73
  /* Each result eases in; honours reduced motion. */
74
- .lp-cmd-item[data-v-8d42f8db] {
74
+ .lp-cmd-item[data-v-2880ef37] {
75
75
  --rise: 3px;
76
76
  animation: rise-in 140ms ease-out both;
77
77
  }
78
78
  @media (prefers-reduced-motion: reduce) {
79
- .lp-cmd-item[data-v-8d42f8db] {
79
+ .lp-cmd-item[data-v-2880ef37] {
80
80
  animation: none;
81
81
  }
82
82
  }
@@ -1,7 +1,7 @@
1
1
  declare const _default: typeof __VLS_export;
2
2
  export default _default;
3
3
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
4
- tone?: "info" | "error" | "action" | "muted" | "outline" | "success" | "warning" | "neutral" | "brand" | "danger" | "ok" | "accent" | undefined;
4
+ tone?: "info" | "error" | "action" | "muted" | "outline" | "success" | "warning" | "accent" | "neutral" | "brand" | "danger" | "ok" | undefined;
5
5
  /** `sm` is the one that does not disturb a text-sm line it sits on. */
6
6
  size?: "md" | "sm" | "lg" | undefined;
7
7
  dot?: boolean;
@@ -12,7 +12,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
12
12
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
13
13
  remove: () => any;
14
14
  }, string, import("vue").PublicProps, Readonly<{
15
- tone?: "info" | "error" | "action" | "muted" | "outline" | "success" | "warning" | "neutral" | "brand" | "danger" | "ok" | "accent" | undefined;
15
+ tone?: "info" | "error" | "action" | "muted" | "outline" | "success" | "warning" | "accent" | "neutral" | "brand" | "danger" | "ok" | undefined;
16
16
  /** `sm` is the one that does not disturb a text-sm line it sits on. */
17
17
  size?: "md" | "sm" | "lg" | undefined;
18
18
  dot?: boolean;
@@ -23,7 +23,7 @@ import { parseCommandQuery, searchCommandItems, applyQueryFilters, parsePaletteQ
23
23
  import { PALETTE_MODES, fallbackRows, readRecent, resolveRecentItems, recentVisible, commandHasPreview, matchModePrefix, modeChipLabel, pushRecent, toRecentItem } from "./commandPalette.js";
24
24
  import { usePortalTarget, useOutsideGuard } from "../composables/useView.js";
25
25
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
26
- import '../assets/LpCommandPalette-Rtbg669l.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
26
+ import '../assets/LpCommandPalette-DOIZHw-g.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
27
27
  const _hoisted_2 = ["title", "onClick"];
28
28
  const _hoisted_3 = ["readonly", "aria-activedescendant", "placeholder", "onKeydown"];
29
29
  const _hoisted_4 = { class: "shrink-0 rounded-small border border-line px-1.5 py-0.5 text-[10px] text-muted" };
@@ -677,6 +677,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
677
677
  run(c);
678
678
  }
679
679
  async function run(row) {
680
+ if (!props.open) return;
680
681
  if (!row || row.disabled || executing.value) return;
681
682
  const c = fallbackOf.get(row) ?? row;
682
683
  const group = moreOf.get(row);
@@ -1291,7 +1292,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1291
1292
  };
1292
1293
  }
1293
1294
  });
1294
- const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8d42f8db"]]);
1295
+ const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-2880ef37"]]);
1295
1296
  export {
1296
1297
  LpCommandPalette as default
1297
1298
  };
@@ -42,9 +42,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
42
42
  }>, {
43
43
  disabled: boolean;
44
44
  align: "start" | "center" | "end";
45
+ touch: "hold" | "none";
45
46
  side: "top" | "right" | "bottom" | "left";
46
47
  sideOffset: number;
47
- touch: "hold" | "none";
48
48
  openDelay: number;
49
49
  closeDelay: number;
50
50
  arrow: boolean;
@@ -1,8 +1,22 @@
1
1
  import { useAttrs, computed, toValue } from "vue";
2
- import { cn } from "tailwind-variants";
2
+ import { extendTailwindMerge } from "tailwind-merge";
3
+ import { cx } from "tailwind-variants";
4
+ const kitMerge = extendTailwindMerge({
5
+ extend: {
6
+ theme: {
7
+ radius: ["control", "card", "pill", "inner", "small"],
8
+ shadow: ["panel"],
9
+ ease: ["emphasized", "travel", "settle"]
10
+ }
11
+ }
12
+ });
13
+ function merge(...classes) {
14
+ const joined = cx(...classes);
15
+ return joined ? kitMerge(joined) : "";
16
+ }
3
17
  function useMergedClass(own) {
4
18
  const attrs = useAttrs();
5
- return computed(() => cn(toValue(own), attrs.class) ?? "");
19
+ return computed(() => merge(toValue(own), attrs.class));
6
20
  }
7
21
  function useMergedAttrs(own) {
8
22
  const attrs = useAttrs();
@@ -15,7 +29,7 @@ function useMergedAttrs(own) {
15
29
  };
16
30
  }
17
31
  function mergeClass(...classes) {
18
- return cn(...classes) ?? "";
32
+ return merge(...classes);
19
33
  }
20
34
  export {
21
35
  mergeClass,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.73.4",
3
+ "version": "0.73.6",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -1250,6 +1250,10 @@ function onRowClick(event: MouseEvent, c: Command) {
1250
1250
  }
1251
1251
 
1252
1252
  async function run(row: Command | undefined) {
1253
+ // A closing palette has already reset to its first rows, where the command
1254
+ // just run sits again as recent: an Enter that lands during the fade ran it
1255
+ // a second time (two snapshots for one pick).
1256
+ if (!props.open) return
1253
1257
  if (!row || row.disabled || executing.value) return
1254
1258
  const c = fallbackOf.get(row) ?? row
1255
1259
  // The highlight stays on the same index, which is now the first row that
@@ -1,5 +1,6 @@
1
1
  import { computed, useAttrs, type ComputedRef, type MaybeRefOrGetter, toValue } from "vue"
2
- import { cn } from "tailwind-variants"
2
+ import { extendTailwindMerge } from "tailwind-merge"
3
+ import { cx } from "tailwind-variants"
3
4
 
4
5
  /*
5
6
  * "The class the consumer passed should win."
@@ -23,6 +24,28 @@ import { cn } from "tailwind-variants"
23
24
  * the component said nothing about shadows.
24
25
  */
25
26
 
27
+ /*
28
+ * tailwind-merge knows Tailwind's own scales only, so the kit's named tokens
29
+ * (`rounded-card`, `shadow-panel`, `ease-emphasized`) looked like unrelated
30
+ * classes to it: `class="rounded-card"` on a box that rounds itself
31
+ * `rounded-control` kept both, and stylesheet order picked the control radius.
32
+ * Named here from tokens.css, so a consumer's token wins like any utility.
33
+ */
34
+ const kitMerge = extendTailwindMerge({
35
+ extend: {
36
+ theme: {
37
+ radius: ["control", "card", "pill", "inner", "small"],
38
+ shadow: ["panel"],
39
+ ease: ["emphasized", "travel", "settle"],
40
+ },
41
+ },
42
+ })
43
+
44
+ function merge(...classes: (string | undefined | null | false)[]): string {
45
+ const joined = cx(...classes)
46
+ return joined ? kitMerge(joined) : ""
47
+ }
48
+
26
49
  /**
27
50
  * Merges the component's own classes with the `class` attribute the consumer
28
51
  * passed, resolving Tailwind conflicts in the consumer's favour.
@@ -43,7 +66,7 @@ export function useMergedClass(
43
66
  const attrs = useAttrs()
44
67
  // `cn` returns undefined when everything it was given was empty; a class
45
68
  // binding is happier with "" than with undefined.
46
- return computed(() => cn(toValue(own), attrs.class as string | undefined) ?? "")
69
+ return computed(() => merge(toValue(own), attrs.class as string | undefined))
47
70
  }
48
71
 
49
72
  /**
@@ -82,5 +105,5 @@ export function useMergedAttrs(own: MaybeRefOrGetter<string | undefined>): {
82
105
  * component merging a class onto a child rather than its own root.
83
106
  */
84
107
  export function mergeClass(...classes: (string | undefined | null | false)[]): string {
85
- return cn(...classes) ?? ""
108
+ return merge(...classes)
86
109
  }