@leavepulse/ui 0.37.2 → 0.37.3

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.
@@ -11,17 +11,17 @@
11
11
  * fade before closing the gap and the whole list lurches at the end instead of
12
12
  * gliding.
13
13
  */
14
- .lp-row-enter-active[data-v-63738e53],
15
- .lp-row-leave-active[data-v-63738e53] {
14
+ .lp-row-enter-active[data-v-e0bb036b],
15
+ .lp-row-leave-active[data-v-e0bb036b] {
16
16
  transition:
17
17
  opacity var(--duration-fast) var(--ease-emphasized),
18
18
  transform var(--duration-fast) var(--ease-emphasized);
19
19
  }
20
- .lp-row-move[data-v-63738e53] {
20
+ .lp-row-move[data-v-e0bb036b] {
21
21
  transition: transform var(--duration-medium) var(--ease-emphasized);
22
22
  }
23
- .lp-row-enter-from[data-v-63738e53],
24
- .lp-row-leave-to[data-v-63738e53] {
23
+ .lp-row-enter-from[data-v-e0bb036b],
24
+ .lp-row-leave-to[data-v-e0bb036b] {
25
25
  opacity: 0;
26
26
  transform: translateX(-0.5rem);
27
27
  }
@@ -35,7 +35,7 @@
35
35
  * drops out of the table layout entirely. Nothing sits below this row to be
36
36
  * dragged around, so simply not animating its exit costs nothing.
37
37
  */
38
- .lp-row-empty.lp-row-leave-active[data-v-63738e53] {
38
+ .lp-row-empty.lp-row-leave-active[data-v-e0bb036b] {
39
39
  display: none;
40
40
  }
41
41
 
@@ -50,9 +50,9 @@
50
50
  /* A filter that redraws the list is information, not decoration: with motion
51
51
  turned down the rows change without animating rather than not changing. */
52
52
  @media (prefers-reduced-motion: reduce) {
53
- .lp-row-enter-active[data-v-63738e53],
54
- .lp-row-leave-active[data-v-63738e53],
55
- .lp-row-move[data-v-63738e53] {
53
+ .lp-row-enter-active[data-v-e0bb036b],
54
+ .lp-row-leave-active[data-v-e0bb036b],
55
+ .lp-row-move[data-v-e0bb036b] {
56
56
  transition: none;
57
57
  }
58
58
  }
@@ -1,4 +1,4 @@
1
- import { defineComponent, ref, computed, shallowRef, watch, onBeforeUnmount, openBlock, createElementBlock, createVNode, mergeProps, withCtx, createElementVNode, normalizeClass, createCommentVNode, Fragment, renderList, normalizeStyle, createBlock, createTextVNode, toDisplayString, TransitionGroup, unref, withModifiers, renderSlot, nextTick } from "vue";
1
+ import { defineComponent, useAttrs, computed, ref, shallowRef, watch, onBeforeUnmount, openBlock, createElementBlock, normalizeClass, createVNode, mergeProps, withCtx, createElementVNode, createCommentVNode, Fragment, renderList, normalizeStyle, createBlock, createTextVNode, toDisplayString, TransitionGroup, unref, withModifiers, renderSlot, nextTick } from "vue";
2
2
  import { _ as _sfc_main$3 } from "../chunks/LpCheckbox-CVccKYaH.js";
3
3
  import { _ as _sfc_main$2 } from "../chunks/LpContextMenu-B6WBLleS.js";
4
4
  import { _ as _sfc_main$4 } from "../chunks/LpIcon-CCnX5_2j.js";
@@ -7,20 +7,19 @@ import { _ as _sfc_main$1 } from "../chunks/LpScrollArea-D8xyKXcF.js";
7
7
  import { useAsyncTask } from "../composables/useAsyncTask.js";
8
8
  import { useRovingFocus } from "../composables/useRovingFocus.js";
9
9
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
10
- import '../assets/LpTable-BbOFmZfc.css';const _hoisted_1 = { class: "flex flex-col gap-3" };
11
- const _hoisted_2 = { class: "border-b border-line bg-surface-soft" };
12
- const _hoisted_3 = {
10
+ import '../assets/LpTable-BgPLJOXa.css';const _hoisted_1 = { class: "border-b border-line bg-surface-soft" };
11
+ const _hoisted_2 = {
13
12
  key: 0,
14
13
  class: "w-px px-4 py-3"
15
14
  };
16
- const _hoisted_4 = ["aria-sort"];
17
- const _hoisted_5 = ["onClick"];
18
- const _hoisted_6 = {
15
+ const _hoisted_3 = ["aria-sort"];
16
+ const _hoisted_4 = ["onClick"];
17
+ const _hoisted_5 = {
19
18
  key: "lp-table-empty",
20
19
  class: "lp-row-empty"
21
20
  };
22
- const _hoisted_7 = ["colspan"];
23
- const _hoisted_8 = ["onContextmenu", "onClick"];
21
+ const _hoisted_6 = ["colspan"];
22
+ const _hoisted_7 = ["onContextmenu", "onClick"];
24
23
  const __default__ = { inheritAttrs: false };
25
24
  const _sfc_main = /* @__PURE__ */ defineComponent({
26
25
  ...__default__,
@@ -51,6 +50,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
51
50
  emits: ["update:selected", "update:sort", "rowClick"],
52
51
  setup(__props, { expose: __expose, emit: __emit }) {
53
52
  const props = __props;
53
+ const attrs = useAttrs();
54
+ const rootClass = computed(() => attrs.class);
55
+ const scrollAttrs = computed(() => {
56
+ const { class: _class, ...rest } = attrs;
57
+ return rest;
58
+ });
54
59
  const emit = __emit;
55
60
  function keyFor(row, index) {
56
61
  if (typeof props.rowKey === "function") return props.rowKey(row);
@@ -351,10 +356,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
351
356
  () => props.stickyHeader && headHeight.value ? `${headHeight.value}px` : void 0
352
357
  );
353
358
  return (_ctx, _cache) => {
354
- return openBlock(), createElementBlock("div", _hoisted_1, [
355
- createVNode(_sfc_main$1, mergeProps(_ctx.$attrs, {
359
+ return openBlock(), createElementBlock("div", {
360
+ class: normalizeClass(["flex flex-col gap-3", rootClass.value])
361
+ }, [
362
+ createVNode(_sfc_main$1, mergeProps(scrollAttrs.value, {
356
363
  fade: false,
357
- class: "rounded-card border border-line",
364
+ class: "min-h-0 flex-1 rounded-card border border-line",
358
365
  style: __props.load && floor.value ? { minHeight: `${floor.value + 2}px` } : void 0,
359
366
  "bar-inset-top": barInsetTop.value
360
367
  }), {
@@ -374,8 +381,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
374
381
  ref: headEl,
375
382
  class: normalizeClass(__props.stickyHeader ? "sticky top-0 z-10 bg-surface-soft" : "")
376
383
  }, [
377
- createElementVNode("tr", _hoisted_2, [
378
- __props.selectable ? (openBlock(), createElementBlock("th", _hoisted_3, [
384
+ createElementVNode("tr", _hoisted_1, [
385
+ __props.selectable ? (openBlock(), createElementBlock("th", _hoisted_2, [
379
386
  createVNode(_sfc_main$3, {
380
387
  "model-value": allChecked.value,
381
388
  indeterminate: someChecked.value,
@@ -417,13 +424,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
417
424
  activeSort.value?.key === col.key ? "opacity-100" : "opacity-40 group-hover/sort:opacity-70"
418
425
  ])
419
426
  }, null, 8, ["name", "class"]))
420
- ], 10, _hoisted_5)
427
+ ], 10, _hoisted_4)
421
428
  ]),
422
429
  _: 2
423
430
  }, 1032, ["items"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
424
431
  createTextVNode(toDisplayString(col.label), 1)
425
432
  ], 64))
426
- ], 14, _hoisted_4);
433
+ ], 14, _hoisted_3);
427
434
  }), 128))
428
435
  ])
429
436
  ], 2),
@@ -435,7 +442,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
435
442
  ref: (el) => unref(roving).setContainer(el?.$el ?? null)
436
443
  }, {
437
444
  default: withCtx(() => [
438
- displayRows.value.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_6, [
445
+ displayRows.value.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_5, [
439
446
  createElementVNode("td", {
440
447
  colspan: colSpan.value,
441
448
  class: "px-4 py-10 text-center text-muted"
@@ -446,7 +453,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
446
453
  class: normalizeClass(["mx-auto mb-2 opacity-60", unref(loading) ? "animate-spin" : ""])
447
454
  }, null, 8, ["name", "class"]),
448
455
  createElementVNode("div", null, toDisplayString(unref(loading) ? __props.loadingLabel : failed.value ? __props.errorLabel : __props.emptyLabel), 1)
449
- ], 8, _hoisted_7)
456
+ ], 8, _hoisted_6)
450
457
  ])) : createCommentVNode("", true),
451
458
  (openBlock(true), createElementBlock(Fragment, null, renderList(displayRows.value, (row, index) => {
452
459
  return openBlock(), createElementBlock("tr", mergeProps({
@@ -481,7 +488,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
481
488
  ], true)
482
489
  ], 2);
483
490
  }), 128))
484
- ], 16, _hoisted_8);
491
+ ], 16, _hoisted_7);
485
492
  }), 128))
486
493
  ]),
487
494
  _: 3
@@ -501,11 +508,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
501
508
  "page-size": __props.pageSize,
502
509
  disabled: unref(loading)
503
510
  }, null, 8, ["page", "total", "page-size", "disabled"])) : createCommentVNode("", true)
504
- ]);
511
+ ], 2);
505
512
  };
506
513
  }
507
514
  });
508
- const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-63738e53"]]);
515
+ const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-e0bb036b"]]);
509
516
  export {
510
517
  LpTable as default
511
518
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.37.2",
3
+ "version": "0.37.3",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -5,7 +5,7 @@ export default { inheritAttrs: false }
5
5
  </script>
6
6
 
7
7
  <script setup lang="ts" generic="T extends Record<string, unknown>">
8
- import { computed, nextTick, onBeforeUnmount, ref, shallowRef, watch } from "vue"
8
+ import { computed, nextTick, onBeforeUnmount, ref, shallowRef, useAttrs, watch } from "vue"
9
9
  import LpCheckbox from "./LpCheckbox.vue"
10
10
  import LpContextMenu, { type ContextMenuItemDef } from "./LpContextMenu.vue"
11
11
  import LpIcon from "./LpIcon.vue"
@@ -132,6 +132,21 @@ const props = withDefaults(
132
132
  },
133
133
  )
134
134
 
135
+ /*
136
+ * Layout classes belong on the root, not on the scroll area. Since the pager
137
+ * wrapper became the root, a caller's `min-h-0 flex-1` landed on the inner
138
+ * scroll area while the wrapper kept sizing to its content — in a flex column
139
+ * the table grew past its container and its bottom edge was clipped away.
140
+ * Everything else (style, aria, listeners) still goes to the scroll area, so a
141
+ * `max-height` keeps capping the scrolling part.
142
+ */
143
+ const attrs = useAttrs()
144
+ const rootClass = computed(() => attrs.class)
145
+ const scrollAttrs = computed(() => {
146
+ const { class: _class, ...rest } = attrs
147
+ return rest
148
+ })
149
+
135
150
  const emit = defineEmits<{
136
151
  (e: "update:selected", value: RowKey[]): void
137
152
  (e: "update:sort", value: SortState | null): void
@@ -577,11 +592,11 @@ const barInsetTop = computed(() =>
577
592
  <template>
578
593
  <!-- No top fade: a sticky header sits in the masked band and would be dimmed
579
594
  by it. The bottom edge is left crisp with it for symmetry. -->
580
- <div class="flex flex-col gap-3">
595
+ <div class="flex flex-col gap-3" :class="rootClass">
581
596
  <LpScrollArea
582
- v-bind="$attrs"
597
+ v-bind="scrollAttrs"
583
598
  :fade="false"
584
- class="rounded-card border border-line"
599
+ class="min-h-0 flex-1 rounded-card border border-line"
585
600
  :style="load && floor ? { minHeight: `${floor + 2}px` } : undefined"
586
601
  :bar-inset-top="barInsetTop"
587
602
  >