@leavepulse/ui 0.93.0 → 0.93.2

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,28 +6,28 @@
6
6
  * outside and only the dots between facts are seen. A cell whose slot drew
7
7
  * nothing (a v-if that failed, an empty value) is left out, dot and all.
8
8
  */
9
- .lp-line[data-v-5ac91b9e] {
9
+ .lp-line[data-v-a346ca36] {
10
10
  --lp-line-sep: 1rem;
11
11
  }
12
- .lp-line-row[data-v-5ac91b9e] {
12
+ .lp-line-row[data-v-a346ca36] {
13
13
  margin-left: calc(-1 * var(--lp-line-sep));
14
14
  }
15
15
 
16
16
  /* The dot lives in the field's own left padding, so whatever the cell draws,
17
17
  a word or a block of two lines, starts after it and never in the clipped
18
18
  strip. */
19
- .lp-line-field[data-v-5ac91b9e] {
19
+ .lp-line-field[data-v-a346ca36] {
20
20
  position: relative;
21
21
  padding-left: var(--lp-line-sep);
22
22
  }
23
- .lp-line-field[data-v-5ac91b9e]::before {
23
+ .lp-line-field[data-v-a346ca36]::before {
24
24
  content: "·" / "";
25
25
  position: absolute;
26
26
  left: 0;
27
27
  width: var(--lp-line-sep);
28
28
  text-align: center;
29
29
  }
30
- .lp-line-field[data-v-5ac91b9e]:has(> .lp-line-value:empty) {
30
+ .lp-line-field[data-v-a346ca36]:has(> .lp-line-value:empty) {
31
31
  display: none;
32
32
  }
33
33
 
@@ -43,17 +43,17 @@
43
43
  * fade before closing the gap and the whole list lurches at the end instead of
44
44
  * gliding.
45
45
  */
46
- .lp-row-enter-active[data-v-5ac91b9e],
47
- .lp-row-leave-active[data-v-5ac91b9e] {
46
+ .lp-row-enter-active[data-v-a346ca36],
47
+ .lp-row-leave-active[data-v-a346ca36] {
48
48
  transition:
49
49
  opacity var(--duration-fast) var(--ease-emphasized),
50
50
  transform var(--duration-fast) var(--ease-emphasized);
51
51
  }
52
- .lp-row-move[data-v-5ac91b9e] {
52
+ .lp-row-move[data-v-a346ca36] {
53
53
  transition: transform var(--duration-medium) var(--ease-emphasized);
54
54
  }
55
- .lp-row-enter-from[data-v-5ac91b9e],
56
- .lp-row-leave-to[data-v-5ac91b9e] {
55
+ .lp-row-enter-from[data-v-a346ca36],
56
+ .lp-row-leave-to[data-v-a346ca36] {
57
57
  opacity: 0;
58
58
  transform: translateX(-0.5rem);
59
59
  }
@@ -67,7 +67,7 @@
67
67
  * drops out of the table layout entirely. Nothing sits below this row to be
68
68
  * dragged around, so simply not animating its exit costs nothing.
69
69
  */
70
- .lp-row-empty.lp-row-leave-active[data-v-5ac91b9e] {
70
+ .lp-row-empty.lp-row-leave-active[data-v-a346ca36] {
71
71
  display: none;
72
72
  }
73
73
 
@@ -86,7 +86,7 @@
86
86
  * once anything is selected. An earlier version collapsed the column to nothing
87
87
  * and floated the hover box over the first cell, where it sat on the text.
88
88
  */
89
- .lp-tick[data-v-5ac91b9e] {
89
+ .lp-tick[data-v-a346ca36] {
90
90
  display: flex;
91
91
  align-items: center;
92
92
  max-width: 0;
@@ -98,17 +98,17 @@
98
98
  padding var(--duration-medium) var(--ease-emphasized),
99
99
  opacity var(--duration-fast) ease;
100
100
  }
101
- .lp-tick-open[data-v-5ac91b9e] {
101
+ .lp-tick-open[data-v-a346ca36] {
102
102
  max-width: 3.25rem;
103
103
  padding-inline: 1rem;
104
104
  opacity: 1;
105
105
  }
106
- .lp-tick-hidden[data-v-5ac91b9e],
107
- .lp-tick-cue[data-v-5ac91b9e] {
106
+ .lp-tick-hidden[data-v-a346ca36],
107
+ .lp-tick-cue[data-v-a346ca36] {
108
108
  opacity: 0;
109
109
  }
110
- tr:hover .lp-tick-cue[data-v-5ac91b9e],
111
- .lp-tick-cue[data-v-5ac91b9e]:focus-within {
110
+ tr:hover .lp-tick-cue[data-v-a346ca36],
111
+ .lp-tick-cue[data-v-a346ca36]:focus-within {
112
112
  opacity: 1;
113
113
  }
114
114
 
@@ -116,15 +116,15 @@ tr:hover .lp-tick-cue[data-v-5ac91b9e],
116
116
  turned down the rows change without animating rather than not changing. */
117
117
  /* Only where there is a hover to reveal it; a finger long-presses instead. */
118
118
  @media (hover: none) {
119
- tr:hover .lp-tick-cue[data-v-5ac91b9e] {
119
+ tr:hover .lp-tick-cue[data-v-a346ca36] {
120
120
  opacity: 0;
121
121
  }
122
122
 
123
123
  /* Nor is there anything for the column's width to hold until then: on a
124
124
  touch screen it stays closed until a long press starts selecting, and
125
125
  eases open like the rest of the column. */
126
- .lp-tick-hidden[data-v-5ac91b9e],
127
- .lp-tick-cue[data-v-5ac91b9e] {
126
+ .lp-tick-hidden[data-v-a346ca36],
127
+ .lp-tick-cue[data-v-a346ca36] {
128
128
  max-width: 0;
129
129
  padding-inline: 0;
130
130
  }
@@ -134,7 +134,7 @@ tr:hover .lp-tick-cue[data-v-5ac91b9e] {
134
134
  * A list line's tick opens from nothing, as the table's column does, so lines
135
135
  * do not carry an empty gap until selection starts.
136
136
  */
137
- .lp-tick-line[data-v-5ac91b9e] {
137
+ .lp-tick-line[data-v-a346ca36] {
138
138
  max-width: 2rem;
139
139
  opacity: 1;
140
140
  }
@@ -144,28 +144,28 @@ tr:hover .lp-tick-cue[data-v-5ac91b9e] {
144
144
  * open; a cue shows it only while
145
145
  * the card is pointed at or holds focus, the same rule as a row's.
146
146
  */
147
- .lp-tick-card[data-v-5ac91b9e] {
147
+ .lp-tick-card[data-v-a346ca36] {
148
148
  max-width: none;
149
149
  padding-inline: 0;
150
150
  opacity: 1;
151
151
  }
152
- .lp-tick[data-cue][data-v-5ac91b9e] {
152
+ .lp-tick[data-cue][data-v-a346ca36] {
153
153
  opacity: 0;
154
154
  }
155
- .lp-item:hover .lp-tick[data-cue][data-v-5ac91b9e],
156
- .lp-tick[data-cue][data-v-5ac91b9e]:focus-within {
155
+ .lp-item:hover .lp-tick[data-cue][data-v-a346ca36],
156
+ .lp-tick[data-cue][data-v-a346ca36]:focus-within {
157
157
  opacity: 1;
158
158
  }
159
159
  @media (hover: none) {
160
- .lp-item:hover .lp-tick[data-cue][data-v-5ac91b9e] {
160
+ .lp-item:hover .lp-tick[data-cue][data-v-a346ca36] {
161
161
  opacity: 0;
162
162
  }
163
163
  }
164
164
  @media (prefers-reduced-motion: reduce) {
165
- .lp-row-enter-active[data-v-5ac91b9e],
166
- .lp-row-leave-active[data-v-5ac91b9e],
167
- .lp-row-move[data-v-5ac91b9e],
168
- .lp-tick[data-v-5ac91b9e] {
165
+ .lp-row-enter-active[data-v-a346ca36],
166
+ .lp-row-leave-active[data-v-a346ca36],
167
+ .lp-row-move[data-v-a346ca36],
168
+ .lp-tick[data-v-a346ca36] {
169
169
  transition: none;
170
170
  }
171
171
  }
@@ -34,7 +34,7 @@ import { toCsv, downloadFile, fileStem } from "./exportData.js";
34
34
  import { toHiddenSets, sameHidden, summarizeShown, parseTableState, mergeRestored, serializeTableState, fromHiddenSets } from "./tableFilter.js";
35
35
  import { resolveRowMenu } from "./tableRowMenu.js";
36
36
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
37
- import '../assets/LpTable-gpdZSVMX.css';const _hoisted_1 = {
37
+ import '../assets/LpTable-DxnthVz4.css';const _hoisted_1 = {
38
38
  key: 0,
39
39
  class: "flex min-h-8 flex-wrap items-center gap-x-3 gap-y-2 pb-3 text-xs"
40
40
  };
@@ -141,6 +141,7 @@ const _hoisted_48 = {
141
141
  class: "lp-line-label"
142
142
  };
143
143
  const _hoisted_49 = { class: "lp-line-value" };
144
+ const _hoisted_50 = ["aria-expanded", "aria-label", "onClick"];
144
145
  const __default__ = { inheritAttrs: false };
145
146
  const _sfc_main = /* @__PURE__ */ defineComponent({
146
147
  ...__default__,
@@ -232,7 +233,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
232
233
  noMatches: "No rows match the filters",
233
234
  resetFilters: "Reset filters",
234
235
  rowCount: "{shown} of {total}",
235
- rowsTotal: "{total} rows",
236
+ rowsTotal: "Rows: {total}",
236
237
  selectedCount: "{count} selected",
237
238
  clearSelection: "Clear selection",
238
239
  pageSelected: "All {count} on this page are selected.",
@@ -1873,7 +1874,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1873
1874
  ])
1874
1875
  ])) : createCommentVNode("", true)
1875
1876
  ], true)
1876
- ]))
1877
+ ])),
1878
+ expansionOn.value && canExpand(entry.row) ? (openBlock(), createElementBlock("button", {
1879
+ key: 3,
1880
+ type: "button",
1881
+ class: normalizeClass(["inline-grid size-6 shrink-0 place-items-center rounded-small text-muted outline-none transition-colors duration-fast hover:text-ink focus-visible:ring-2 focus-visible:ring-ring", activeLayout.value === "cards" ? "absolute right-2 bottom-2" : ""]),
1882
+ "aria-expanded": expandedKeys.value.has(keyFor(entry.row, entry.index)),
1883
+ "aria-label": expandedKeys.value.has(keyFor(entry.row, entry.index)) ? text.value.collapseRow : text.value.expandRow,
1884
+ onClick: withModifiers(($event) => toggleExpanded(keyFor(entry.row, entry.index)), ["stop"]),
1885
+ onPointerdown: _cache[10] || (_cache[10] = withModifiers(() => {
1886
+ }, ["stop"]))
1887
+ }, [
1888
+ createVNode(_sfc_main$5, {
1889
+ name: "lucide:chevron-right",
1890
+ size: 14,
1891
+ class: normalizeClass(["transition-transform duration-fast motion-reduce:transition-none", expandedKeys.value.has(keyFor(entry.row, entry.index)) ? "rotate-90" : ""])
1892
+ }, null, 8, ["class"])
1893
+ ], 42, _hoisted_50)) : createCommentVNode("", true)
1877
1894
  ], 16, _hoisted_35))
1878
1895
  ], 64);
1879
1896
  }), 128))
@@ -1889,7 +1906,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1889
1906
  __props.load && total.value > __props.pageSize ? (openBlock(), createBlock(_sfc_main$h, {
1890
1907
  key: 0,
1891
1908
  page: page.value,
1892
- "onUpdate:page": _cache[10] || (_cache[10] = ($event) => page.value = $event),
1909
+ "onUpdate:page": _cache[11] || (_cache[11] = ($event) => page.value = $event),
1893
1910
  total: total.value,
1894
1911
  "page-size": __props.pageSize,
1895
1912
  disabled: busy.value
@@ -1898,7 +1915,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1898
1915
  };
1899
1916
  }
1900
1917
  });
1901
- const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-5ac91b9e"]]);
1918
+ const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a346ca36"]]);
1902
1919
  export {
1903
1920
  LpTable as default
1904
1921
  };
@@ -75,9 +75,9 @@ export interface ChartAnnotation {
75
75
  }
76
76
  /**
77
77
  * Which x labels to print with every `stride`-th one shown. The last point is
78
- * always labelled (it is usually "now"), and when it lands within half a
79
- * stride to the previous shown label that one gives way: "20 22 23" read as
80
- * one smudge at the end of an hourly axis.
78
+ * always labelled (it is usually "now"), and when it lands closer than a
79
+ * full stride to the previous shown label that one gives way: "20 22 23" read
80
+ * as one smudge at the end of an hourly axis.
81
81
  */
82
82
  export declare function xLabelIndices(count: number, stride: number): number[];
83
83
  /** The x index a marker points at, or -1 when it names nothing on the axis. */
@@ -7,7 +7,7 @@ function xLabelIndices(count, stride) {
7
7
  for (let i = 0; i < count; i += step) out.push(i);
8
8
  const last = count - 1;
9
9
  if (out[out.length - 1] !== last) {
10
- if (out.length > 1 && last - out[out.length - 1] <= step / 2) out.pop();
10
+ if (out.length > 1 && last - out[out.length - 1] < step) out.pop();
11
11
  out.push(last);
12
12
  }
13
13
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.93.0",
3
+ "version": "0.93.2",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -523,7 +523,7 @@ const labelSet = useLabels<TableLabels>(
523
523
  noMatches: "No rows match the filters",
524
524
  resetFilters: "Reset filters",
525
525
  rowCount: "{shown} of {total}",
526
- rowsTotal: "{total} rows",
526
+ rowsTotal: "Rows: {total}",
527
527
  selectedCount: "{count} selected",
528
528
  clearSelection: "Clear selection",
529
529
  pageSelected: "All {count} on this page are selected.",
@@ -2413,6 +2413,20 @@ usePaletteCommands(() => {
2413
2413
  </div>
2414
2414
  </slot>
2415
2415
  </div>
2416
+ <!-- The table's chevron, in a line and a card too: without it an
2417
+ expandable row drew its detail panel but nothing opened it. -->
2418
+ <button
2419
+ v-if="expansionOn && canExpand(entry.row)"
2420
+ type="button"
2421
+ class="inline-grid size-6 shrink-0 place-items-center rounded-small text-muted outline-none transition-colors duration-fast hover:text-ink focus-visible:ring-2 focus-visible:ring-ring"
2422
+ :class="activeLayout === 'cards' ? 'absolute right-2 bottom-2' : ''"
2423
+ :aria-expanded="expandedKeys.has(keyFor(entry.row, entry.index))"
2424
+ :aria-label="expandedKeys.has(keyFor(entry.row, entry.index)) ? text.collapseRow : text.expandRow"
2425
+ @click.stop="toggleExpanded(keyFor(entry.row, entry.index))"
2426
+ @pointerdown.stop
2427
+ >
2428
+ <LpIcon name="lucide:chevron-right" :size="14" class="transition-transform duration-fast motion-reduce:transition-none" :class="expandedKeys.has(keyFor(entry.row, entry.index)) ? 'rotate-90' : ''" />
2429
+ </button>
2416
2430
  </div>
2417
2431
  </template>
2418
2432
  </TransitionGroup>
@@ -91,9 +91,9 @@ export interface ChartAnnotation {
91
91
 
92
92
  /**
93
93
  * Which x labels to print with every `stride`-th one shown. The last point is
94
- * always labelled (it is usually "now"), and when it lands within half a
95
- * stride to the previous shown label that one gives way: "20 22 23" read as
96
- * one smudge at the end of an hourly axis.
94
+ * always labelled (it is usually "now"), and when it lands closer than a
95
+ * full stride to the previous shown label that one gives way: "20 22 23" read
96
+ * as one smudge at the end of an hourly axis.
97
97
  */
98
98
  export function xLabelIndices(count: number, stride: number): number[] {
99
99
  if (count <= 0) return []
@@ -102,7 +102,10 @@ export function xLabelIndices(count: number, stride: number): number[] {
102
102
  for (let i = 0; i < count; i += step) out.push(i)
103
103
  const last = count - 1
104
104
  if (out[out.length - 1] !== last) {
105
- if (out.length > 1 && last - out[out.length - 1] <= step / 2) out.pop()
105
+ // The stride is the spacing at which labels fit, so a last label closer
106
+ // than a full step to the one before would print over it ("10:03 PM10:09
107
+ // PM"): the earlier one gives way.
108
+ if (out.length > 1 && last - out[out.length - 1] < step) out.pop()
106
109
  out.push(last)
107
110
  }
108
111
  return out