@leavepulse/ui 0.92.1 → 0.93.0

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.
@@ -2,6 +2,8 @@ import { defineComponent, computed, openBlock, createElementBlock, normalizeStyl
2
2
  import { Handle, Position } from "@vue-flow/core";
3
3
  import { _ as _sfc_main$2 } from "./LpBadge-Bh5roBr_.js";
4
4
  import { _ as _sfc_main$1 } from "./LpStatus-C6GqSHJj.js";
5
+ import { TONE_COLOR } from "../components/meter.js";
6
+ import { STATUS_LOOK } from "../components/status.js";
5
7
  const _hoisted_1 = { class: "px-[11px] pb-2.5 pt-[9px]" };
6
8
  const _hoisted_2 = { class: "flex items-center gap-[7px]" };
7
9
  const _hoisted_3 = { class: "text-[13px] text-[var(--accent)]" };
@@ -74,15 +76,25 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
74
76
  const accentLine = computed(
75
77
  () => `color-mix(in srgb, ${accent.value} 35%, var(--color-line))`
76
78
  );
79
+ const state = computed(
80
+ () => props.data.status ?? (props.data.online === void 0 ? void 0 : props.data.online ? "online" : "down")
81
+ );
82
+ const troubled = computed(() => state.value !== void 0 && state.value !== "online");
83
+ const lost = computed(() => state.value === "down" || state.value === "offline");
84
+ const stateColor = computed(
85
+ () => state.value ? `color-mix(in srgb, ${TONE_COLOR[STATUS_LOOK[state.value].tone]} 50%, transparent)` : void 0
86
+ );
77
87
  return (_ctx, _cache) => {
78
88
  return openBlock(), createElementBlock("div", {
79
- class: normalizeClass(["w-[168px] overflow-hidden rounded-card border bg-surface-raised shadow-panel transition-[border-color,box-shadow]", [
80
- __props.selected ? "border-[var(--accent)]" : __props.data.online === false ? "border-dashed border-danger/50" : "border-[var(--accent-line)]"
89
+ class: normalizeClass(["w-[168px] overflow-hidden rounded-card border bg-surface-raised shadow-panel transition-[border-color,box-shadow,opacity] duration-medium ease-[var(--ease-emphasized)]", [
90
+ __props.selected ? "border-[var(--accent)]" : troubled.value ? "border-[var(--state-line)]" : "border-[var(--accent-line)]",
91
+ !__props.selected && lost.value ? "border-dashed" : ""
81
92
  ]]),
82
93
  style: normalizeStyle({
83
94
  "--accent": accent.value,
84
95
  "--accent-line": accentLine.value,
85
- opacity: __props.data.dimmed ? 0.3 : __props.data.online === false ? 0.75 : 1,
96
+ "--state-line": stateColor.value,
97
+ opacity: __props.data.dimmed ? 0.3 : lost.value ? 0.75 : 1,
86
98
  ...__props.selected ? { boxShadow: "0 0 0 2px color-mix(in srgb, var(--accent) 40%, transparent), var(--shadow-panel)" } : {}
87
99
  })
88
100
  }, [
@@ -97,18 +109,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
97
109
  class: "!size-2 !border-2 !border-[var(--accent)] !bg-surface"
98
110
  }, null, 8, ["position"]),
99
111
  createElementVNode("div", {
100
- class: normalizeClass(["h-[3px]", __props.data.online === false ? "bg-danger/50" : "bg-[var(--accent)]"])
112
+ class: normalizeClass(["h-[3px] transition-[background-color] duration-medium ease-[var(--ease-emphasized)]", troubled.value ? "bg-[var(--state-line)]" : "bg-[var(--accent)]"])
101
113
  }, null, 2),
102
114
  createElementVNode("div", _hoisted_1, [
103
115
  createElementVNode("div", _hoisted_2, [
104
116
  createElementVNode("span", _hoisted_3, toDisplayString(icon.value), 1),
105
117
  createElementVNode("span", _hoisted_4, toDisplayString(__props.data.name), 1),
106
- __props.data.online !== void 0 ? (openBlock(), createBlock(_sfc_main$1, {
118
+ state.value ? (openBlock(), createBlock(_sfc_main$1, {
107
119
  key: 0,
108
- state: __props.data.online ? "online" : "down",
109
- pulse: __props.data.online,
120
+ state: state.value,
110
121
  "hide-label": ""
111
- }, null, 8, ["state", "pulse"])) : createCommentVNode("", true)
122
+ }, null, 8, ["state"])) : createCommentVNode("", true)
112
123
  ]),
113
124
  createElementVNode("div", _hoisted_5, [
114
125
  createElementVNode("span", _hoisted_6, toDisplayString(__props.data.roleLabel ?? __props.data.role), 1),
@@ -10,7 +10,7 @@ import { nodeWindow, isHTMLElement } from "../composables/realm.js";
10
10
  import { backgroundOf, resolveCssColor, svgToPng } from "../components/exportData.js";
11
11
  import { _ as _sfc_main$6 } from "./LpButton-BvVoF-PO.js";
12
12
  import { _ as _sfc_main$7 } from "./LpIcon-CxHFPwKt.js";
13
- import { _ as _sfc_main$3 } from "./LpInfraNode-BYiMFDnA.js";
13
+ import { _ as _sfc_main$3 } from "./LpInfraNode-tD5x5YOy.js";
14
14
  import { _ as _sfc_main$5 } from "./LpInput-DGMpxrcg.js";
15
15
  import { _ as _sfc_main$1 } from "./LpLaneNode-Bqcdm8Rf.js";
16
16
  import { _ as _sfc_main$2 } from "./LpServiceNode-Cln2ntdw.js";
@@ -8,6 +8,7 @@
8
8
  * component doesn't reach apps that only import the kit's token css.
9
9
  */
10
10
  import { type NodeProps } from "@vue-flow/core";
11
+ import { type StatusKind } from "./status";
11
12
  export interface InfraNodeData {
12
13
  name: string;
13
14
  /** Role key: selects the colour/glyph, and shown as-is unless `roleLabel`. */
@@ -18,7 +19,15 @@ export interface InfraNodeData {
18
19
  */
19
20
  roleLabel?: string;
20
21
  overlay?: string;
22
+ /** Up or down. Superseded by `status` when that is set. */
21
23
  online?: boolean;
24
+ /**
25
+ * The node's state in the kit's status words, for a fleet that knows more
26
+ * than up and down: a box that serves but takes no instruction, one merely
27
+ * unreachable, one starting. Drawn with LpStatus's light and tone; only
28
+ * `down` and `offline` take the dashed, faded frame of a lost machine.
29
+ */
30
+ status?: StatusKind;
22
31
  kind?: string;
23
32
  project?: string;
24
33
  /** Control-plane firewall rule count on this host (badge when > 0). */
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpInfraNode-BYiMFDnA.js";
1
+ import { _ as _sfc_main } from "../chunks/LpInfraNode-tD5x5YOy.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -14,7 +14,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
14
14
  /** Always show the CSS still, never start WebGL: for a low-power mode or a screenshot. */
15
15
  still?: boolean;
16
16
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
17
- fallback: (reason: "compile" | "unavailable" | "slow" | "lost") => any;
17
+ fallback: (reason: "compile" | "unavailable" | "lost" | "slow") => any;
18
18
  }, string, import("vue").PublicProps, Readonly<{
19
19
  preset?: ShaderPreset;
20
20
  /** How strongly the theme colours show over the surface, 0–1. Lower for a backdrop under body text. */
@@ -28,7 +28,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
28
28
  /** Always show the CSS still, never start WebGL: for a low-power mode or a screenshot. */
29
29
  still?: boolean;
30
30
  }> & Readonly<{
31
- onFallback?: ((reason: "compile" | "unavailable" | "slow" | "lost") => any) | undefined;
31
+ onFallback?: ((reason: "compile" | "unavailable" | "lost" | "slow") => any) | undefined;
32
32
  }>, {
33
33
  speed: number;
34
34
  paused: boolean;
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpTopologyCanvas-CQ0l6A5h.js";
1
+ import { _ as _sfc_main } from "../chunks/LpTopologyCanvas-B1YFfMaq.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
package/dist/index.js CHANGED
@@ -54,7 +54,7 @@ import { _ as _31 } from "./chunks/LpFormField-jbM7K1Hg.js";
54
54
  import { _ as _32 } from "./chunks/LpIcon-CxHFPwKt.js";
55
55
  import { i, b, a, c } from "./chunks/icons-C8ccRCKw.js";
56
56
  import { default as default10 } from "./components/LpImageEditor.vue.js";
57
- import { _ as _33 } from "./chunks/LpInfraNode-BYiMFDnA.js";
57
+ import { _ as _33 } from "./chunks/LpInfraNode-tD5x5YOy.js";
58
58
  import { _ as _34 } from "./chunks/LpInput-DGMpxrcg.js";
59
59
  import { _ as _35 } from "./chunks/LpLightbox-a24V_0Wk.js";
60
60
  import { fileNameOf, isVideoItem } from "./components/lightbox.js";
@@ -131,7 +131,7 @@ import { _ as _87 } from "./chunks/LpHintLayer-nuMqfzvy.js";
131
131
  import { _ as _88 } from "./chunks/LpHints-ByAd3a76.js";
132
132
  import { HINT_SIGNALS, contextMenuTip, createHintSystem, dropzoneTip, hintKey, hintSummary, hotkeyTip, localHintStorage, noteDropzone, noteHotkeyTarget, paletteTip, provideHintSystem, runningHintSystem, useHintSystem } from "./composables/useHintSystem.js";
133
133
  import { _ as _89 } from "./chunks/LpTooltipProvider-CftjV7Xc.js";
134
- import { _ as _90 } from "./chunks/LpTopologyCanvas-CQ0l6A5h.js";
134
+ import { _ as _90 } from "./chunks/LpTopologyCanvas-B1YFfMaq.js";
135
135
  import { clusterGraph, diffTopology, findPath, layeredLayout, neighborhood, topologyToSvg } from "./components/topologyGraph.js";
136
136
  import { _ as _91 } from "./chunks/LpUptimeBar-Dt6SY_-m.js";
137
137
  import { addLeaf, addTab, countBlocks, countLeaves, deserializeLayout, makeLayout, moveLeaf, removeBlock, removeLeaf, reorderTab, resizeAt, serializeLayout, setActiveTab } from "./layout/tree.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.92.1",
3
+ "version": "0.93.0",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -12,6 +12,8 @@ import { Handle, Position, type NodeProps } from "@vue-flow/core"
12
12
  import { computed } from "vue"
13
13
  import LpBadge from "./LpBadge.vue"
14
14
  import LpStatus from "./LpStatus.vue"
15
+ import { TONE_COLOR } from "./meter"
16
+ import { STATUS_LOOK, type StatusKind } from "./status"
15
17
 
16
18
  export interface InfraNodeData {
17
19
  name: string
@@ -23,7 +25,15 @@ export interface InfraNodeData {
23
25
  */
24
26
  roleLabel?: string
25
27
  overlay?: string
28
+ /** Up or down. Superseded by `status` when that is set. */
26
29
  online?: boolean
30
+ /**
31
+ * The node's state in the kit's status words, for a fleet that knows more
32
+ * than up and down: a box that serves but takes no instruction, one merely
33
+ * unreachable, one starting. Drawn with LpStatus's light and tone; only
34
+ * `down` and `offline` take the dashed, faded frame of a lost machine.
35
+ */
36
+ status?: StatusKind
27
37
  kind?: string
28
38
  project?: string
29
39
  /** Control-plane firewall rule count on this host (badge when > 0). */
@@ -126,6 +136,18 @@ const icon = computed(() => role.value.icon)
126
136
  const accentLine = computed(
127
137
  () => `color-mix(in srgb, ${accent.value} 35%, var(--color-line))`,
128
138
  )
139
+
140
+ /** `status` when given, else the old up/down flag read as a status. */
141
+ const state = computed<StatusKind | undefined>(
142
+ () => props.data.status ?? (props.data.online === undefined ? undefined : props.data.online ? "online" : "down"),
143
+ )
144
+ /** A state other than healthy takes the frame and the role bar in its own tone. */
145
+ const troubled = computed(() => state.value !== undefined && state.value !== "online")
146
+ /** No contact at all: dashed and faded, the way a lost machine has always looked. */
147
+ const lost = computed(() => state.value === "down" || state.value === "offline")
148
+ const stateColor = computed(() =>
149
+ state.value ? `color-mix(in srgb, ${TONE_COLOR[STATUS_LOOK[state.value].tone]} 50%, transparent)` : undefined,
150
+ )
129
151
  </script>
130
152
 
131
153
  <template>
@@ -139,18 +161,16 @@ const accentLine = computed(
139
161
  signals on a node agree instead of arguing.
140
162
  -->
141
163
  <div
142
- class="w-[168px] overflow-hidden rounded-card border bg-surface-raised shadow-panel transition-[border-color,box-shadow]"
164
+ class="w-[168px] overflow-hidden rounded-card border bg-surface-raised shadow-panel transition-[border-color,box-shadow,opacity] duration-medium ease-[var(--ease-emphasized)]"
143
165
  :class="[
144
- selected
145
- ? 'border-[var(--accent)]'
146
- : data.online === false
147
- ? 'border-dashed border-danger/50'
148
- : 'border-[var(--accent-line)]',
166
+ selected ? 'border-[var(--accent)]' : troubled ? 'border-[var(--state-line)]' : 'border-[var(--accent-line)]',
167
+ !selected && lost ? 'border-dashed' : '',
149
168
  ]"
150
169
  :style="{
151
170
  '--accent': accent,
152
171
  '--accent-line': accentLine,
153
- opacity: data.dimmed ? 0.3 : data.online === false ? 0.75 : 1,
172
+ '--state-line': stateColor,
173
+ opacity: data.dimmed ? 0.3 : lost ? 0.75 : 1,
154
174
  ...(selected
155
175
  ? { boxShadow: '0 0 0 2px color-mix(in srgb, var(--accent) 40%, transparent), var(--shadow-panel)' }
156
176
  : {}),
@@ -167,23 +187,18 @@ const accentLine = computed(
167
187
  class="!size-2 !border-2 !border-[var(--accent)] !bg-surface"
168
188
  />
169
189
 
170
- <!-- The role bar reads as "this node is alive and is a proxy"; on an
171
- offline host it must not keep asserting the first half. -->
190
+ <!-- The role bar reads as "this node is alive and is a proxy"; on a host
191
+ in trouble it must not keep asserting the first half. -->
172
192
  <div
173
- class="h-[3px]"
174
- :class="data.online === false ? 'bg-danger/50' : 'bg-[var(--accent)]'"
193
+ class="h-[3px] transition-[background-color] duration-medium ease-[var(--ease-emphasized)]"
194
+ :class="troubled ? 'bg-[var(--state-line)]' : 'bg-[var(--accent)]'"
175
195
  />
176
196
  <div class="px-[11px] pb-2.5 pt-[9px]">
177
197
  <div class="flex items-center gap-[7px]">
178
198
  <span class="text-[13px] text-[var(--accent)]">{{ icon }}</span>
179
199
  <span class="flex-1 truncate text-[13px] font-semibold text-ink">{{ data.name }}</span>
180
- <!-- The kit's status light: a live host breathes, a lost one is a steady red. -->
181
- <LpStatus
182
- v-if="data.online !== undefined"
183
- :state="data.online ? 'online' : 'down'"
184
- :pulse="data.online"
185
- hide-label
186
- />
200
+ <!-- The kit's status light, with LpStatus's own tone and pulse for each state. -->
201
+ <LpStatus v-if="state" :state="state" hide-label />
187
202
  </div>
188
203
  <div class="mt-1.5 flex items-center justify-between">
189
204
  <span class="text-[10px] font-semibold uppercase tracking-wide text-[var(--accent)]">