@procaaso/alphinity-ui-components 1.12.0 → 1.14.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.
- package/IMPLEMENTATION_GUIDE.md +1351 -1351
- package/README.md +98 -98
- package/dist/index.cjs +188 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +140 -20
- package/dist/index.d.ts +140 -20
- package/dist/index.js +184 -53
- package/dist/index.js.map +1 -1
- package/package.json +85 -85
package/dist/index.js
CHANGED
|
@@ -277,6 +277,13 @@ var ISA_UNKNOWN_DARK = {
|
|
|
277
277
|
bg: "#23263a",
|
|
278
278
|
border: "#6f74a3"
|
|
279
279
|
};
|
|
280
|
+
var FORCED_MARK_COLOR = {
|
|
281
|
+
fill: "#ede9fe",
|
|
282
|
+
stroke: "#5b21b6",
|
|
283
|
+
bg: "#ede9fe",
|
|
284
|
+
text: "#5b21b6",
|
|
285
|
+
border: "#7c3aed"
|
|
286
|
+
};
|
|
280
287
|
var DEFAULT_STATUS_COLORS = {
|
|
281
288
|
normal: { fill: "#888888", stroke: "#6b6b6b", bg: "#888888", text: "#ffffff", border: "#6b6b6b" },
|
|
282
289
|
warning: { fill: "#f59e0b", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
@@ -285,14 +292,8 @@ var DEFAULT_STATUS_COLORS = {
|
|
|
285
292
|
off: { fill: "#edeeef", stroke: "#000000", bg: "#666666", text: "#ffffff", border: "#4b5563" },
|
|
286
293
|
starting: { fill: "#90EE90", stroke: "#22c55e", bg: "#90EE90", text: "#000000", border: "#22c55e" },
|
|
287
294
|
stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
|
|
288
|
-
unknown: { fill: ISA_UNKNOWN.bg, stroke: ISA_UNKNOWN.border, bg: ISA_UNKNOWN.bg, text: ISA_UNKNOWN.fg, border: ISA_UNKNOWN.border }
|
|
289
|
-
|
|
290
|
-
var FORCED_MARK_COLOR = {
|
|
291
|
-
fill: "#ede9fe",
|
|
292
|
-
stroke: "#5b21b6",
|
|
293
|
-
bg: "#ede9fe",
|
|
294
|
-
text: "#5b21b6",
|
|
295
|
-
border: "#7c3aed"
|
|
295
|
+
unknown: { fill: ISA_UNKNOWN.bg, stroke: ISA_UNKNOWN.border, bg: ISA_UNKNOWN.bg, text: ISA_UNKNOWN.fg, border: ISA_UNKNOWN.border },
|
|
296
|
+
forced: FORCED_MARK_COLOR
|
|
296
297
|
};
|
|
297
298
|
var STATUS_ALIASES = {
|
|
298
299
|
running: "normal",
|
|
@@ -1138,6 +1139,10 @@ var NodeControlsPanel = ({
|
|
|
1138
1139
|
// src/components/DeviceControlPanel/DeviceControlPanel.tsx
|
|
1139
1140
|
import React6, { useState as useState5, useEffect as useEffect2 } from "react";
|
|
1140
1141
|
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1142
|
+
var DISABLED_BUTTON_BG = "#e5e7eb";
|
|
1143
|
+
var DISABLED_BUTTON_TEXT = "#4b5563";
|
|
1144
|
+
var DISABLED_BUTTON_BORDER = "#6b7280";
|
|
1145
|
+
var DISABLED_BUTTON_HATCH = "repeating-linear-gradient(135deg, rgba(0,0,0,0.10) 0px, rgba(0,0,0,0.10) 4px, transparent 4px, transparent 10px)";
|
|
1141
1146
|
function DeviceControlPanelImpl({
|
|
1142
1147
|
binding,
|
|
1143
1148
|
onClose,
|
|
@@ -1218,6 +1223,36 @@ function DeviceControlPanelImpl({
|
|
|
1218
1223
|
const statusEntry = resolveStatusColor(binding.state.status, binding.theme?.statusColors);
|
|
1219
1224
|
const statusColor = statusEntry.bg;
|
|
1220
1225
|
const isUnknownStatus = normalizeDeviceStatus(binding.state.status) === "unknown";
|
|
1226
|
+
const startStopRowShown = binding.display?.showStartStop !== false && (activeCapabilities?.canStart === true || activeCapabilities?.canStop === true);
|
|
1227
|
+
const startEnabledNow = activeCapabilities?.canStart === true && activeCapabilities?.startEnabled !== false && !startPending;
|
|
1228
|
+
const stopEnabledNow = activeCapabilities?.canStop === true && activeCapabilities?.stopEnabled !== false;
|
|
1229
|
+
const startStopFontPx = Math.max(18, Math.round(18 * fontScale));
|
|
1230
|
+
const startStopButtonStyle = (enabled, enabledBg) => ({
|
|
1231
|
+
flex: 1,
|
|
1232
|
+
minWidth: 0,
|
|
1233
|
+
height: Math.max(touchSize, 56),
|
|
1234
|
+
borderRadius: "6px",
|
|
1235
|
+
fontSize: `${startStopFontPx}px`,
|
|
1236
|
+
fontWeight: 700,
|
|
1237
|
+
fontFamily: "Arial, sans-serif",
|
|
1238
|
+
letterSpacing: "0.5px",
|
|
1239
|
+
...enabled ? {
|
|
1240
|
+
backgroundColor: enabledBg,
|
|
1241
|
+
color: "#ffffff",
|
|
1242
|
+
border: "2px solid transparent",
|
|
1243
|
+
cursor: "pointer",
|
|
1244
|
+
opacity: 1
|
|
1245
|
+
} : {
|
|
1246
|
+
// Disabled look that does not depend on colour (ISA-101): a dashed
|
|
1247
|
+
// border and a diagonal hatch. A grey fill alone is not enough.
|
|
1248
|
+
backgroundColor: DISABLED_BUTTON_BG,
|
|
1249
|
+
backgroundImage: DISABLED_BUTTON_HATCH,
|
|
1250
|
+
color: DISABLED_BUTTON_TEXT,
|
|
1251
|
+
border: `2px dashed ${DISABLED_BUTTON_BORDER}`,
|
|
1252
|
+
cursor: "not-allowed",
|
|
1253
|
+
opacity: 1
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1221
1256
|
const handleModeChange = (mode) => {
|
|
1222
1257
|
onModeChange?.(mode);
|
|
1223
1258
|
};
|
|
@@ -1403,6 +1438,7 @@ function DeviceControlPanelImpl({
|
|
|
1403
1438
|
/* @__PURE__ */ jsx9(
|
|
1404
1439
|
"div",
|
|
1405
1440
|
{
|
|
1441
|
+
"data-testid": "device-status-dot",
|
|
1406
1442
|
style: {
|
|
1407
1443
|
width: "10px",
|
|
1408
1444
|
height: "10px",
|
|
@@ -1988,50 +2024,45 @@ function DeviceControlPanelImpl({
|
|
|
1988
2024
|
param.id
|
|
1989
2025
|
))
|
|
1990
2026
|
] }),
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
},
|
|
2031
|
-
children: stopPending ? "STOPPING\u2026" : "STOP"
|
|
2032
|
-
}
|
|
2033
|
-
)
|
|
2034
|
-
] }),
|
|
2027
|
+
startStopRowShown && /* @__PURE__ */ jsxs8(
|
|
2028
|
+
"div",
|
|
2029
|
+
{
|
|
2030
|
+
"data-testid": "start-stop-row",
|
|
2031
|
+
style: { display: "flex", gap: spacing.gap, marginBottom: spacing.marginBottom },
|
|
2032
|
+
children: [
|
|
2033
|
+
/* @__PURE__ */ jsx9(
|
|
2034
|
+
"button",
|
|
2035
|
+
{
|
|
2036
|
+
type: "button",
|
|
2037
|
+
"data-control": "start",
|
|
2038
|
+
"data-enabled": startEnabledNow ? "true" : "false",
|
|
2039
|
+
onClick: () => {
|
|
2040
|
+
if (startEnabledNow) onStart?.();
|
|
2041
|
+
},
|
|
2042
|
+
disabled: !startEnabledNow,
|
|
2043
|
+
"aria-busy": startPending || void 0,
|
|
2044
|
+
style: startStopButtonStyle(startEnabledNow, "#10b981"),
|
|
2045
|
+
children: startPending ? "STARTING\u2026" : "START"
|
|
2046
|
+
}
|
|
2047
|
+
),
|
|
2048
|
+
/* @__PURE__ */ jsx9(
|
|
2049
|
+
"button",
|
|
2050
|
+
{
|
|
2051
|
+
type: "button",
|
|
2052
|
+
"data-control": "stop",
|
|
2053
|
+
"data-enabled": stopEnabledNow ? "true" : "false",
|
|
2054
|
+
onClick: () => {
|
|
2055
|
+
if (stopEnabledNow) onStop?.();
|
|
2056
|
+
},
|
|
2057
|
+
disabled: !stopEnabledNow,
|
|
2058
|
+
"aria-busy": stopPending || void 0,
|
|
2059
|
+
style: startStopButtonStyle(stopEnabledNow, "#ef4444"),
|
|
2060
|
+
children: stopPending ? "STOPPING\u2026" : "STOP"
|
|
2061
|
+
}
|
|
2062
|
+
)
|
|
2063
|
+
]
|
|
2064
|
+
}
|
|
2065
|
+
),
|
|
2035
2066
|
activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ jsx9("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: activeCapabilities.customActions.map((action) => {
|
|
2036
2067
|
const actionDisabled = action.disabled === true;
|
|
2037
2068
|
return /* @__PURE__ */ jsxs8(
|
|
@@ -5031,6 +5062,32 @@ function writeAppearanceValue(node, field, value) {
|
|
|
5031
5062
|
return { metadata: { ...node.metadata, [field.key]: value } };
|
|
5032
5063
|
}
|
|
5033
5064
|
|
|
5065
|
+
// src/diagram/badges/nodeBadgeGlyphs.ts
|
|
5066
|
+
var PROHIBIT_GLYPH = {
|
|
5067
|
+
id: "prohibit",
|
|
5068
|
+
svgContent: '<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2.4"/><line x1="5.6" y1="18.4" x2="18.4" y2="5.6" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/>'
|
|
5069
|
+
};
|
|
5070
|
+
var builtInBadgeGlyphs = {
|
|
5071
|
+
[PROHIBIT_GLYPH.id]: PROHIBIT_GLYPH
|
|
5072
|
+
};
|
|
5073
|
+
var customBadgeGlyphs = {};
|
|
5074
|
+
function registerBadgeGlyph(glyph) {
|
|
5075
|
+
customBadgeGlyphs[glyph.id] = glyph;
|
|
5076
|
+
}
|
|
5077
|
+
function registerBadgeGlyphs(glyphs) {
|
|
5078
|
+
if (Array.isArray(glyphs)) {
|
|
5079
|
+
glyphs.forEach((glyph) => registerBadgeGlyph(glyph));
|
|
5080
|
+
} else {
|
|
5081
|
+
Object.values(glyphs).forEach((glyph) => registerBadgeGlyph(glyph));
|
|
5082
|
+
}
|
|
5083
|
+
}
|
|
5084
|
+
function getBadgeGlyph(glyphId) {
|
|
5085
|
+
return customBadgeGlyphs[glyphId] ?? builtInBadgeGlyphs[glyphId];
|
|
5086
|
+
}
|
|
5087
|
+
function getAvailableBadgeGlyphs() {
|
|
5088
|
+
return [...Object.keys(customBadgeGlyphs), ...Object.keys(builtInBadgeGlyphs)];
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5034
5091
|
// src/components/PIDCanvas/NodeRenderer.tsx
|
|
5035
5092
|
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5036
5093
|
var HATCH_TILE_SIZE = 7;
|
|
@@ -5040,6 +5097,75 @@ var HATCH_STRIPE_OPACITY = 85 / 255;
|
|
|
5040
5097
|
function isUnknownNode(node) {
|
|
5041
5098
|
return node.positionUnknown === true || normalizeDeviceStatus(node.status) === "unknown";
|
|
5042
5099
|
}
|
|
5100
|
+
var DEFAULT_BADGE_CORNER = "top-right";
|
|
5101
|
+
var DEFAULT_BADGE_SIZE = 14;
|
|
5102
|
+
var DEFAULT_BADGE_COLOR = "#111827";
|
|
5103
|
+
var DEFAULT_BADGE_BACKGROUND = "#d1d5db";
|
|
5104
|
+
var BADGE_GLYPH_BOX = 24;
|
|
5105
|
+
var BADGE_BLINK_KEYFRAME_ID = "pid-node-badge-blink-keyframes";
|
|
5106
|
+
var BADGE_BLINK_KEYFRAME_NAME = "pid-node-badge-blink";
|
|
5107
|
+
function ensureBadgeBlinkKeyframes() {
|
|
5108
|
+
if (typeof document === "undefined") return;
|
|
5109
|
+
if (document.getElementById(BADGE_BLINK_KEYFRAME_ID)) return;
|
|
5110
|
+
const style = document.createElement("style");
|
|
5111
|
+
style.id = BADGE_BLINK_KEYFRAME_ID;
|
|
5112
|
+
style.textContent = `@keyframes ${BADGE_BLINK_KEYFRAME_NAME}{0%{opacity:1}50%{opacity:.15}100%{opacity:1}}`;
|
|
5113
|
+
document.head.appendChild(style);
|
|
5114
|
+
}
|
|
5115
|
+
function badgeCenter(corner, vb, size) {
|
|
5116
|
+
const margin = size / 4;
|
|
5117
|
+
switch (corner) {
|
|
5118
|
+
case "top-left":
|
|
5119
|
+
return { x: -margin, y: -margin };
|
|
5120
|
+
case "bottom-left":
|
|
5121
|
+
return { x: -margin, y: vb.height + margin };
|
|
5122
|
+
case "bottom-right":
|
|
5123
|
+
return { x: vb.width + margin, y: vb.height + margin };
|
|
5124
|
+
case "top-right":
|
|
5125
|
+
default:
|
|
5126
|
+
return { x: vb.width + margin, y: -margin };
|
|
5127
|
+
}
|
|
5128
|
+
}
|
|
5129
|
+
function renderNodeBadge(badge, vb, rotation) {
|
|
5130
|
+
const glyphDef = getBadgeGlyph(badge.glyph);
|
|
5131
|
+
const size = badge.size ?? DEFAULT_BADGE_SIZE;
|
|
5132
|
+
const color = badge.color ?? DEFAULT_BADGE_COLOR;
|
|
5133
|
+
const backgroundColor = badge.backgroundColor ?? DEFAULT_BADGE_BACKGROUND;
|
|
5134
|
+
const corner = badge.corner ?? DEFAULT_BADGE_CORNER;
|
|
5135
|
+
const { x: cx, y: cy } = badgeCenter(corner, vb, size);
|
|
5136
|
+
const radius = size / 2;
|
|
5137
|
+
const glyphScale = size / BADGE_GLYPH_BOX;
|
|
5138
|
+
let blinkStyle;
|
|
5139
|
+
if (badge.blink) {
|
|
5140
|
+
ensureBadgeBlinkKeyframes();
|
|
5141
|
+
blinkStyle = {
|
|
5142
|
+
animation: `${BADGE_BLINK_KEYFRAME_NAME} ${badge.blinkPeriodMs}ms ease-in-out infinite`
|
|
5143
|
+
};
|
|
5144
|
+
}
|
|
5145
|
+
return /* @__PURE__ */ jsxs13(
|
|
5146
|
+
"g",
|
|
5147
|
+
{
|
|
5148
|
+
"data-node-badge": badge.glyph,
|
|
5149
|
+
"data-badge-corner": corner,
|
|
5150
|
+
"data-badge-blink": badge.blink ? "true" : "false",
|
|
5151
|
+
"aria-label": badge.label,
|
|
5152
|
+
role: badge.label ? "img" : void 0,
|
|
5153
|
+
transform: rotation ? `translate(${cx}, ${cy}) rotate(${-rotation})` : `translate(${cx}, ${cy})`,
|
|
5154
|
+
style: blinkStyle,
|
|
5155
|
+
children: [
|
|
5156
|
+
/* @__PURE__ */ jsx17("circle", { r: radius, fill: backgroundColor }),
|
|
5157
|
+
glyphDef && /* @__PURE__ */ jsx17(
|
|
5158
|
+
"g",
|
|
5159
|
+
{
|
|
5160
|
+
color,
|
|
5161
|
+
transform: `scale(${glyphScale}) translate(${-BADGE_GLYPH_BOX / 2}, ${-BADGE_GLYPH_BOX / 2})`,
|
|
5162
|
+
dangerouslySetInnerHTML: { __html: glyphDef.svgContent }
|
|
5163
|
+
}
|
|
5164
|
+
)
|
|
5165
|
+
]
|
|
5166
|
+
}
|
|
5167
|
+
);
|
|
5168
|
+
}
|
|
5043
5169
|
function NodeRendererImpl({
|
|
5044
5170
|
nodes: nodes2,
|
|
5045
5171
|
selectedNodeIds,
|
|
@@ -5246,7 +5372,8 @@ function NodeRendererImpl({
|
|
|
5246
5372
|
transform: node.transform.rotation ? `rotate(${-node.transform.rotation}, ${labelX}, ${labelY})` : void 0,
|
|
5247
5373
|
children: node.label || node.id
|
|
5248
5374
|
}
|
|
5249
|
-
)
|
|
5375
|
+
),
|
|
5376
|
+
node.badge && renderNodeBadge(node.badge, vb, node.transform.rotation)
|
|
5250
5377
|
]
|
|
5251
5378
|
},
|
|
5252
5379
|
node.id
|
|
@@ -10341,7 +10468,9 @@ export {
|
|
|
10341
10468
|
generateRoutePoints,
|
|
10342
10469
|
getAppearanceDefaults,
|
|
10343
10470
|
getAppearanceSchema,
|
|
10471
|
+
getAvailableBadgeGlyphs,
|
|
10344
10472
|
getAvailableSymbols,
|
|
10473
|
+
getBadgeGlyph,
|
|
10345
10474
|
getPortWorldPosition,
|
|
10346
10475
|
getSymbolDefinition,
|
|
10347
10476
|
importDiagram,
|
|
@@ -10350,6 +10479,8 @@ export {
|
|
|
10350
10479
|
normalizeDeviceStatus,
|
|
10351
10480
|
overlayStyles,
|
|
10352
10481
|
readAppearanceValue,
|
|
10482
|
+
registerBadgeGlyph,
|
|
10483
|
+
registerBadgeGlyphs,
|
|
10353
10484
|
registerSymbol,
|
|
10354
10485
|
registerSymbols,
|
|
10355
10486
|
resolvePresetColor,
|