@leavepulse/ui 0.22.7 → 0.22.9

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.
@@ -23,11 +23,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
23
23
  selectable: { type: Boolean, default: false },
24
24
  legend: { type: Boolean, default: true },
25
25
  legendPosition: { default: "bottom-left" },
26
+ legendLabels: {},
26
27
  lanes: { default: () => [] },
27
28
  minimap: { type: Boolean, default: true },
28
29
  controls: { type: Boolean, default: true }
29
30
  },
30
- emits: ["connect", "node-select", "node-contextmenu", "edge-contextmenu", "pane-click", "selection-change", "update:nodes", "node-drag-stop", "viewport-change"],
31
+ emits: ["connect", "node-select", "node-activate", "node-contextmenu", "edge-contextmenu", "pane-click", "selection-change", "update:nodes", "node-drag-stop", "viewport-change"],
31
32
  setup(__props, { expose: __expose, emit: __emit }) {
32
33
  const props = __props;
33
34
  const emit = __emit;
@@ -122,6 +123,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
122
123
  );
123
124
  const {
124
125
  onNodeClick,
126
+ onNodeDoubleClick,
125
127
  onNodeContextMenu,
126
128
  onEdgeContextMenu,
127
129
  onPaneClick,
@@ -133,6 +135,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
133
135
  setViewport
134
136
  } = useVueFlow();
135
137
  onNodeClick(({ node }) => emit("node-select", node.id));
138
+ onNodeDoubleClick(({ node }) => emit("node-activate", node.id));
136
139
  onNodeDragStop(
137
140
  ({ node }) => emit("node-drag-stop", { id: node.id, position: { ...node.position } })
138
141
  );
@@ -158,12 +161,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
158
161
  if (props.legendPosition === "bottom-right") return "!bottom-40";
159
162
  return "";
160
163
  });
161
- const legendItems = [
162
- { label: "Network", color: CATEGORY_COLOR.network, width: 2, dash: "0" },
163
- { label: "Depends-on", color: CATEGORY_COLOR.structural, width: 1.5, dash: "1 5" },
164
- { label: "Pending", color: "var(--color-brand)", width: 2, dash: "6 5" },
165
- { label: "Drift", color: "var(--color-danger)", width: 2, dash: "6 5" }
166
- ];
164
+ const legendItems = computed(() => [
165
+ { label: props.legendLabels?.network ?? "Network", color: CATEGORY_COLOR.network, width: 2, dash: "0" },
166
+ {
167
+ label: props.legendLabels?.structural ?? "Depends-on",
168
+ color: CATEGORY_COLOR.structural,
169
+ width: 1.5,
170
+ dash: "1 5"
171
+ },
172
+ { label: props.legendLabels?.pending ?? "Pending", color: "var(--color-brand)", width: 2, dash: "6 5" },
173
+ { label: props.legendLabels?.drift ?? "Drift", color: "var(--color-danger)", width: 2, dash: "6 5" }
174
+ ]);
167
175
  onEdgeContextMenu(({ edge, event }) => {
168
176
  const e = event;
169
177
  e.preventDefault?.();
@@ -213,8 +221,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
213
221
  }, {
214
222
  default: withCtx(() => [
215
223
  createElementVNode("div", _hoisted_1, [
216
- (openBlock(), createElementBlock(Fragment, null, renderList(legendItems, (l) => {
217
- return createElementVNode("div", {
224
+ (openBlock(true), createElementBlock(Fragment, null, renderList(legendItems.value, (l) => {
225
+ return openBlock(), createElementBlock("div", {
218
226
  key: l.label,
219
227
  class: "flex items-center gap-2 text-muted"
220
228
  }, [
@@ -232,7 +240,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
232
240
  ])),
233
241
  createTextVNode(" " + toDisplayString(l.label), 1)
234
242
  ]);
235
- }), 64))
243
+ }), 128))
236
244
  ])
237
245
  ]),
238
246
  _: 1
@@ -90,6 +90,8 @@ type __VLS_Props = {
90
90
  * minimap owns the bottom-right.
91
91
  */
92
92
  legendPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
93
+ /** Rename legend rows to match what this graph's edges actually mean. */
94
+ legendLabels?: Partial<Record<"network" | "structural" | "pending" | "drift", string>>;
93
95
  /**
94
96
  * Background swimlanes drawn beneath the nodes (one per project / overlay).
95
97
  * Non-interactive; pan/zoom with the graph. Empty = no lanes.
@@ -110,6 +112,7 @@ declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {
110
112
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
111
113
  connect: (value: Connection) => any;
112
114
  "node-select": (id: string) => any;
115
+ "node-activate": (id: string) => any;
113
116
  "node-contextmenu": (value: {
114
117
  id: string;
115
118
  x: number;
@@ -138,6 +141,7 @@ declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {
138
141
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
139
142
  onConnect?: ((value: Connection) => any) | undefined;
140
143
  "onNode-select"?: ((id: string) => any) | undefined;
144
+ "onNode-activate"?: ((id: string) => any) | undefined;
141
145
  "onNode-contextmenu"?: ((value: {
142
146
  id: string;
143
147
  x: number;
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpTopologyCanvas-DNmL56pJ.js";
1
+ import { _ as _sfc_main } from "../chunks/LpTopologyCanvas-DCgm_d5G.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ import { D, _ as _56, N, T, b, c, d, e, f, g, i, l, h, j, n, r, t, k, m, u, v }
64
64
  import { _ as _57 } from "./chunks/LpTilt-DuyKbpkA.js";
65
65
  import { _ as _58 } from "./chunks/LpToaster-gDB1EaU3.js";
66
66
  import { _ as _59 } from "./chunks/LpTooltip-D1hbjQWG.js";
67
- import { _ as _60 } from "./chunks/LpTopologyCanvas-DNmL56pJ.js";
67
+ import { _ as _60 } from "./chunks/LpTopologyCanvas-DCgm_d5G.js";
68
68
  import { _ as _61 } from "./chunks/LpUptimeBar-CB366k0O.js";
69
69
  import { deserializeLayout, serializeLayout } from "./layout/tree.js";
70
70
  import { addLeaf, addTab, countBlocks, countLeaves, makeLayout, moveLeaf, removeBlock, removeLeaf, reorderTab, resizeAt, setActiveTab } from "./layout/tree.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.22.7",
3
+ "version": "0.22.9",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -125,6 +125,10 @@ const props = withDefaults(
125
125
  * minimap owns the bottom-right.
126
126
  */
127
127
  legendPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"
128
+ /** Rename legend rows to match what this graph's edges actually mean. */
129
+ legendLabels?: Partial<
130
+ Record<"network" | "structural" | "pending" | "drift", string>
131
+ >
128
132
  /**
129
133
  * Background swimlanes drawn beneath the nodes (one per project / overlay).
130
134
  * Non-interactive; pan/zoom with the graph. Empty = no lanes.
@@ -152,6 +156,8 @@ const props = withDefaults(
152
156
  const emit = defineEmits<{
153
157
  (e: "connect", value: Connection): void
154
158
  (e: "node-select", id: string): void
159
+ /** Double-click — the host's "open this" gesture, distinct from selecting. */
160
+ (e: "node-activate", id: string): void
155
161
  (e: "node-contextmenu", value: { id: string; x: number; y: number }): void
156
162
  (e: "edge-contextmenu", value: { id: string; x: number; y: number }): void
157
163
  (e: "pane-click"): void
@@ -281,6 +287,7 @@ const flowEdges = computed(() =>
281
287
 
282
288
  const {
283
289
  onNodeClick,
290
+ onNodeDoubleClick,
284
291
  onNodeContextMenu,
285
292
  onEdgeContextMenu,
286
293
  onPaneClick,
@@ -292,6 +299,9 @@ const {
292
299
  setViewport,
293
300
  } = useVueFlow()
294
301
  onNodeClick(({ node }) => emit("node-select", node.id))
302
+ // A node usually has two levels of interest — pick it out, or open it — and a
303
+ // single click cannot carry both. Hosts that only need one can ignore this.
304
+ onNodeDoubleClick(({ node }) => emit("node-activate", node.id))
295
305
  // Drag settled → surface the node's final position so the host can persist it.
296
306
  onNodeDragStop(({ node }) =>
297
307
  emit("node-drag-stop", { id: node.id, position: { ...node.position } }),
@@ -327,12 +337,20 @@ const legendOffset = computed(() => {
327
337
  })
328
338
 
329
339
  // Legend rows mirror the edge encoding exactly (same colours/dashes).
330
- const legendItems = [
331
- { label: "Network", color: CATEGORY_COLOR.network, width: 2, dash: "0" },
332
- { label: "Depends-on", color: CATEGORY_COLOR.structural, width: 1.5, dash: "1 5" },
333
- { label: "Pending", color: "var(--color-brand)", width: 2, dash: "6 5" },
334
- { label: "Drift", color: "var(--color-danger)", width: 2, dash: "6 5" },
335
- ] as const
340
+ // What each encoding MEANS depends on what the host is drawing: the same solid
341
+ // line is a transport on a machine graph and a call on a service graph, so
342
+ // "Network" would be wrong half the time. `legendLabels` renames any row.
343
+ const legendItems = computed(() => [
344
+ { label: props.legendLabels?.network ?? "Network", color: CATEGORY_COLOR.network, width: 2, dash: "0" },
345
+ {
346
+ label: props.legendLabels?.structural ?? "Depends-on",
347
+ color: CATEGORY_COLOR.structural,
348
+ width: 1.5,
349
+ dash: "1 5",
350
+ },
351
+ { label: props.legendLabels?.pending ?? "Pending", color: "var(--color-brand)", width: 2, dash: "6 5" },
352
+ { label: props.legendLabels?.drift ?? "Drift", color: "var(--color-danger)", width: 2, dash: "6 5" },
353
+ ])
336
354
 
337
355
  onEdgeContextMenu(({ edge, event }) => {
338
356
  // Right-click an edge → host renders edge actions (change transport, remove…).