@imperosoft/cris-webui-components 1.1.2-beta.0 → 1.1.2-beta.10

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/dist/index.js CHANGED
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  CrisButton: () => CrisButton,
24
+ CrisCoDebug: () => CrisCoDebug,
25
+ CrisCoMatrixListsTie: () => CrisCoMatrixListsTie,
24
26
  CrisGauge: () => CrisGauge,
25
27
  CrisOfflinePage: () => CrisOfflinePage,
26
28
  CrisSlider: () => CrisSlider,
@@ -108,9 +110,12 @@ function CrisButton({
108
110
  iconNameActive,
109
111
  iconClassActive,
110
112
  iconStyleActive,
113
+ selected,
111
114
  showControlFeedback = true,
112
115
  showLocalFeedback = true,
113
116
  suppressKeyClicks = false,
117
+ visible,
118
+ enabled,
114
119
  smartId,
115
120
  className = "",
116
121
  classActive = "",
@@ -121,19 +126,24 @@ function CrisButton({
121
126
  onRelease,
122
127
  debug = false
123
128
  }) {
124
- const log = debug ? (msg, data) => console.log(`[CrisButton:${join}] ${msg}`, data ?? "") : () => {
125
- };
129
+ const debugRef = (0, import_react.useRef)(debug);
130
+ debugRef.current = debug;
131
+ const joinRef = (0, import_react.useRef)(join);
132
+ joinRef.current = join;
133
+ const log = (0, import_react.useCallback)((msg, data) => {
134
+ if (debugRef.current) console.log(`[CrisButton:${joinRef.current}] ${msg}`, data ?? "");
135
+ }, []);
126
136
  const [pressed, setPressed] = (0, import_react.useState)(false);
127
137
  const pressedRef = (0, import_react.useRef)(false);
128
138
  const touchingRef = (0, import_react.useRef)(false);
129
139
  const touchStartedHereRef = (0, import_react.useRef)(false);
130
140
  const feedbackJoin = joinFeedback ?? join;
131
141
  const feedback = (0, import_cris_webui_ch5_core.useDigital)(feedbackJoin ?? 0);
132
- const enabled = (0, import_cris_webui_ch5_core.useDigital)(joinEnable ?? 0);
133
- const visible = (0, import_cris_webui_ch5_core.useDigital)(joinVisible ?? 0);
142
+ const enabledJoin = (0, import_cris_webui_ch5_core.useDigital)(joinEnable ?? 0);
143
+ const visibleJoin = (0, import_cris_webui_ch5_core.useDigital)(joinVisible ?? 0);
134
144
  const dSet = (0, import_cris_webui_ch5_core.useJoinsStore)((state) => state.dSet);
135
- const isEnabled = joinEnable == null ? true : enabled;
136
- const isVisible = joinVisible == null ? true : visible;
145
+ const isEnabled = enabled ?? (joinEnable == null ? true : enabledJoin);
146
+ const isVisible = visible ?? (joinVisible == null ? true : visibleJoin);
137
147
  (0, import_react.useEffect)(() => {
138
148
  log("visibility effect", { isVisible, pressedRef: pressedRef.current });
139
149
  if (!isVisible && pressedRef.current) {
@@ -147,7 +157,7 @@ function CrisButton({
147
157
  dSet(join, false);
148
158
  }
149
159
  }
150
- }, [isVisible, join, smartId, dSet, log]);
160
+ }, [isVisible, join, smartId, dSet]);
151
161
  (0, import_react.useEffect)(() => {
152
162
  return () => {
153
163
  if (pressedRef.current && join != null && smartId == null) {
@@ -156,7 +166,7 @@ function CrisButton({
156
166
  }
157
167
  };
158
168
  }, [join, smartId, dSet, log]);
159
- const hasControlFeedback = showControlFeedback && feedbackJoin != null && feedback;
169
+ const hasControlFeedback = showControlFeedback && (feedbackJoin != null && feedback || selected === true);
160
170
  const hasPressedFeedback = showLocalFeedback && pressed && isEnabled;
161
171
  const isActive = hasControlFeedback || hasPressedFeedback;
162
172
  let currentText = text ?? "";
@@ -1133,9 +1143,466 @@ function CrisOfflinePage({
1133
1143
  ] })
1134
1144
  ] }) });
1135
1145
  }
1146
+
1147
+ // src/components/CrisCoDebug.tsx
1148
+ var import_cris_webui_ch5_core7 = require("@imperosoft/cris-webui-ch5-core");
1149
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1150
+ var defaultStyles = {
1151
+ container: {
1152
+ display: "flex",
1153
+ flexDirection: "column",
1154
+ overflow: "auto",
1155
+ gap: 2
1156
+ },
1157
+ title: {
1158
+ fontSize: 14,
1159
+ fontWeight: 600,
1160
+ padding: "8px 12px",
1161
+ opacity: 0.7
1162
+ },
1163
+ item: {
1164
+ display: "flex",
1165
+ alignItems: "center",
1166
+ padding: "8px 12px",
1167
+ gap: 8,
1168
+ minHeight: 48
1169
+ },
1170
+ info: {
1171
+ flex: 1,
1172
+ minWidth: 0,
1173
+ overflow: "hidden"
1174
+ },
1175
+ moduleName: {
1176
+ fontSize: 14,
1177
+ fontWeight: 600,
1178
+ whiteSpace: "nowrap",
1179
+ overflow: "hidden",
1180
+ textOverflow: "ellipsis"
1181
+ },
1182
+ moduleType: {
1183
+ fontSize: 11,
1184
+ opacity: 0.5
1185
+ },
1186
+ icons: {
1187
+ display: "flex",
1188
+ gap: 4,
1189
+ alignItems: "center",
1190
+ minWidth: 56,
1191
+ justifyContent: "center"
1192
+ },
1193
+ buttons: {
1194
+ display: "flex",
1195
+ gap: 4,
1196
+ alignItems: "center"
1197
+ },
1198
+ iconBox: {
1199
+ width: 24,
1200
+ height: 24,
1201
+ display: "flex",
1202
+ alignItems: "center",
1203
+ justifyContent: "center",
1204
+ position: "relative"
1205
+ }
1206
+ };
1207
+ function ConnectionIcon({ on, type }) {
1208
+ const label = type === "eth" ? "ETH" : "RS";
1209
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1210
+ "div",
1211
+ {
1212
+ style: {
1213
+ ...defaultStyles.iconBox,
1214
+ opacity: on ? 1 : 0.4
1215
+ },
1216
+ title: `${type === "eth" ? "Ethernet" : "RS232"}: ${on ? "Connected" : "Disconnected"}`,
1217
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", children: [
1218
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "1", y: "4", width: "18", height: "12", rx: "2", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
1219
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("text", { x: "10", y: "12.5", textAnchor: "middle", fontSize: "7", fontWeight: "bold", fill: "currentColor", children: label }),
1220
+ on ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "16", cy: "5", r: "3.5", fill: "#4caf50", stroke: "none" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1221
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "16", cy: "5", r: "3.5", fill: "#f44336", stroke: "none" }),
1222
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "14", y1: "3", x2: "18", y2: "7", stroke: "white", strokeWidth: "1.5" })
1223
+ ] })
1224
+ ] })
1225
+ }
1226
+ );
1227
+ }
1228
+ function DebugModuleItem({
1229
+ module: module2,
1230
+ onAction,
1231
+ itemClassName,
1232
+ itemStyle,
1233
+ buttonClassName,
1234
+ buttonActiveClassName,
1235
+ iconEthOn,
1236
+ iconEthOff,
1237
+ iconRs232On,
1238
+ iconRs232Off
1239
+ }) {
1240
+ const name = module2.lb ? `${module2.id} (${module2.lb})` : module2.id;
1241
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1242
+ "div",
1243
+ {
1244
+ className: itemClassName,
1245
+ style: itemClassName ? itemStyle : { ...defaultStyles.item, ...itemStyle },
1246
+ children: [
1247
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: defaultStyles.info, children: [
1248
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: defaultStyles.moduleName, children: name }),
1249
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: defaultStyles.moduleType, children: module2.tp })
1250
+ ] }),
1251
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: defaultStyles.icons, children: [
1252
+ module2.et.vs && (iconEthOn && iconEthOff ? module2.et.on ? iconEthOn : iconEthOff : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConnectionIcon, { on: module2.et.on, type: "eth" })),
1253
+ module2.rs.vs && (iconRs232On && iconRs232Off ? module2.rs.on ? iconRs232On : iconRs232Off : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConnectionIcon, { on: module2.rs.on, type: "rs232" }))
1254
+ ] }),
1255
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: defaultStyles.buttons, children: [
1256
+ module2.md.vs && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1257
+ CrisButton,
1258
+ {
1259
+ selected: module2.md.on,
1260
+ text: "Mod",
1261
+ className: buttonClassName,
1262
+ classActive: buttonActiveClassName,
1263
+ onPress: () => onAction("toggleMod", module2.id)
1264
+ }
1265
+ ),
1266
+ module2.cm.vs && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1267
+ CrisButton,
1268
+ {
1269
+ selected: module2.cm.on,
1270
+ text: "Com",
1271
+ className: buttonClassName,
1272
+ classActive: buttonActiveClassName,
1273
+ onPress: () => onAction("toggleCom", module2.id)
1274
+ }
1275
+ )
1276
+ ] })
1277
+ ]
1278
+ }
1279
+ );
1280
+ }
1281
+ function CrisCoDebug({
1282
+ oid = "__DBG__",
1283
+ title,
1284
+ className,
1285
+ style,
1286
+ itemClassName,
1287
+ itemStyle,
1288
+ buttonClassName,
1289
+ buttonActiveClassName,
1290
+ iconEthOn,
1291
+ iconEthOff,
1292
+ iconRs232On,
1293
+ iconRs232Off
1294
+ }) {
1295
+ const modules = (0, import_cris_webui_ch5_core7.useCustomObject)(oid);
1296
+ const send = (0, import_cris_webui_ch5_core7.useCustomObjectSend)();
1297
+ const handleAction = (action, id) => {
1298
+ send(oid, { action, id });
1299
+ };
1300
+ if (!modules || modules.length === 0) {
1301
+ return null;
1302
+ }
1303
+ const visibleModules = modules.filter((m) => m.vs);
1304
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1305
+ "div",
1306
+ {
1307
+ className,
1308
+ style: className ? style : { ...defaultStyles.container, ...style },
1309
+ children: [
1310
+ title && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: defaultStyles.title, children: title }),
1311
+ visibleModules.map((module2) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1312
+ DebugModuleItem,
1313
+ {
1314
+ module: module2,
1315
+ onAction: handleAction,
1316
+ itemClassName,
1317
+ itemStyle,
1318
+ buttonClassName,
1319
+ buttonActiveClassName,
1320
+ iconEthOn,
1321
+ iconEthOff,
1322
+ iconRs232On,
1323
+ iconRs232Off
1324
+ },
1325
+ module2.id
1326
+ ))
1327
+ ]
1328
+ }
1329
+ );
1330
+ }
1331
+
1332
+ // src/components/CrisCoMatrixListsTie.tsx
1333
+ var import_cris_webui_ch5_core8 = require("@imperosoft/cris-webui-ch5-core");
1334
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1335
+ var defaults = {
1336
+ container: {
1337
+ display: "flex",
1338
+ flexDirection: "row",
1339
+ gap: 8,
1340
+ height: "100%"
1341
+ },
1342
+ list: {
1343
+ flex: 1,
1344
+ display: "flex",
1345
+ flexDirection: "column",
1346
+ overflow: "hidden",
1347
+ minHeight: 0
1348
+ },
1349
+ header: {
1350
+ fontSize: 13,
1351
+ fontWeight: 600,
1352
+ padding: "6px 10px",
1353
+ textTransform: "uppercase",
1354
+ opacity: 0.6,
1355
+ flexShrink: 0
1356
+ },
1357
+ scroll: {
1358
+ flex: 1,
1359
+ minHeight: 0,
1360
+ overflow: "auto",
1361
+ WebkitOverflowScrolling: "touch",
1362
+ display: "flex",
1363
+ flexDirection: "column",
1364
+ gap: 2
1365
+ },
1366
+ item: {
1367
+ display: "flex",
1368
+ alignItems: "center",
1369
+ gap: 6,
1370
+ padding: "6px 10px",
1371
+ minHeight: 40,
1372
+ cursor: "pointer",
1373
+ userSelect: "none"
1374
+ },
1375
+ itemLabel: {
1376
+ flex: 1,
1377
+ fontSize: 13,
1378
+ whiteSpace: "nowrap",
1379
+ overflow: "hidden",
1380
+ textOverflow: "ellipsis"
1381
+ },
1382
+ indicators: {
1383
+ display: "flex",
1384
+ gap: 4,
1385
+ alignItems: "center"
1386
+ },
1387
+ indicator: {
1388
+ width: 8,
1389
+ height: 8,
1390
+ borderRadius: "50%",
1391
+ flexShrink: 0
1392
+ }
1393
+ };
1394
+ function DefaultIoIndicator({ on }) {
1395
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1396
+ "div",
1397
+ {
1398
+ style: {
1399
+ ...defaults.indicator,
1400
+ backgroundColor: on ? "#4caf50" : "#f44336"
1401
+ },
1402
+ title: on ? "Online" : "Offline"
1403
+ }
1404
+ );
1405
+ }
1406
+ function DefaultSignalIndicator({ on }) {
1407
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1408
+ "div",
1409
+ {
1410
+ style: {
1411
+ ...defaults.indicator,
1412
+ backgroundColor: on ? "#2196f3" : "#666"
1413
+ },
1414
+ title: on ? "Signal detected" : "No signal"
1415
+ }
1416
+ );
1417
+ }
1418
+ function MatrixItemRow({
1419
+ item,
1420
+ type,
1421
+ active,
1422
+ showChannels,
1423
+ onSelect,
1424
+ onToggleVideoMute,
1425
+ itemClassName,
1426
+ itemStyle: itemStyleProp,
1427
+ itemActiveClassName,
1428
+ itemActiveStyle,
1429
+ itemDisabledClassName,
1430
+ vmButtonClassName,
1431
+ vmButtonActiveClassName,
1432
+ renderIoIndicator,
1433
+ renderSignalIndicator
1434
+ }) {
1435
+ const isActive = active;
1436
+ const isEnabled = item.sl.en;
1437
+ const classes = [
1438
+ "cris-co-matrix-item",
1439
+ itemClassName,
1440
+ isActive && (itemActiveClassName || "active"),
1441
+ !isEnabled && (itemDisabledClassName || "disabled")
1442
+ ].filter(Boolean).join(" ");
1443
+ const computedStyle = itemClassName ? { ...itemStyleProp } : {
1444
+ ...defaults.item,
1445
+ ...itemStyleProp,
1446
+ ...isActive ? itemActiveStyle : void 0,
1447
+ opacity: isEnabled ? 1 : 0.4
1448
+ };
1449
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: classes, style: computedStyle, children: [
1450
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1451
+ CrisButton,
1452
+ {
1453
+ selected: isActive,
1454
+ enabled: isEnabled,
1455
+ onPress: onSelect,
1456
+ className: `cris-co-matrix-item-btn ${itemActiveClassName ?? ""}`,
1457
+ classActive: itemActiveClassName,
1458
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, width: "100%" }, children: [
1459
+ showChannels && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "cris-co-matrix-ch", style: { flexShrink: 0, opacity: 0.6 }, children: item.id }),
1460
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: defaults.itemLabel, children: item.lb || `${type === "input" ? "Input" : "Output"} ${item.id}` }),
1461
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: defaults.indicators, children: [
1462
+ item.io.vs && (renderIoIndicator ? renderIoIndicator(item.io.on) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DefaultIoIndicator, { on: item.io.on })),
1463
+ item.sg.vs && (renderSignalIndicator ? renderSignalIndicator(item.sg.on) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DefaultSignalIndicator, { on: item.sg.on }))
1464
+ ] })
1465
+ ] })
1466
+ }
1467
+ ),
1468
+ item.vm.vs && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1469
+ CrisButton,
1470
+ {
1471
+ selected: item.vm.on,
1472
+ enabled: item.vm.en,
1473
+ text: "VM",
1474
+ onPress: onToggleVideoMute,
1475
+ className: vmButtonClassName,
1476
+ classActive: vmButtonActiveClassName
1477
+ }
1478
+ )
1479
+ ] });
1480
+ }
1481
+ function CrisCoMatrixListsTie({
1482
+ oid,
1483
+ inputTitle = "Inputs",
1484
+ outputTitle = "Outputs",
1485
+ showChannels = true,
1486
+ className,
1487
+ style,
1488
+ listClassName,
1489
+ listStyle,
1490
+ headerClassName,
1491
+ headerStyle,
1492
+ itemClassName,
1493
+ itemStyle,
1494
+ itemActiveClassName,
1495
+ itemActiveStyle,
1496
+ itemDisabledClassName,
1497
+ vmButtonClassName,
1498
+ vmButtonActiveClassName,
1499
+ renderIoIndicator,
1500
+ renderSignalIndicator
1501
+ }) {
1502
+ const matrix = (0, import_cris_webui_ch5_core8.useCustomObject)(oid);
1503
+ const send = (0, import_cris_webui_ch5_core8.useCustomObjectSend)();
1504
+ if (!matrix) return null;
1505
+ const { si, ip: inputs, op: outputs } = matrix;
1506
+ const handleSelectInput = (id) => {
1507
+ send(oid, { action: "selectInput", id });
1508
+ };
1509
+ const handleTie = (id) => {
1510
+ send(oid, { action: "tie", id });
1511
+ };
1512
+ const handleToggleVideoMute = (type, id) => {
1513
+ send(oid, { action: "toggleVideoMute", type, id });
1514
+ };
1515
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1516
+ "div",
1517
+ {
1518
+ className,
1519
+ style: className ? style : { ...defaults.container, ...style },
1520
+ children: [
1521
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1522
+ "div",
1523
+ {
1524
+ className: listClassName,
1525
+ style: listClassName ? listStyle : { ...defaults.list, ...listStyle },
1526
+ children: [
1527
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1528
+ "div",
1529
+ {
1530
+ className: headerClassName,
1531
+ style: headerClassName ? headerStyle : { ...defaults.header, ...headerStyle },
1532
+ children: inputTitle
1533
+ }
1534
+ ),
1535
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: defaults.scroll, children: inputs?.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1536
+ MatrixItemRow,
1537
+ {
1538
+ item,
1539
+ type: "input",
1540
+ active: si === item.id,
1541
+ showChannels,
1542
+ onSelect: () => handleSelectInput(item.id),
1543
+ onToggleVideoMute: () => handleToggleVideoMute("input", item.id),
1544
+ itemClassName,
1545
+ itemStyle,
1546
+ itemActiveClassName,
1547
+ itemActiveStyle,
1548
+ itemDisabledClassName,
1549
+ vmButtonClassName,
1550
+ vmButtonActiveClassName,
1551
+ renderIoIndicator,
1552
+ renderSignalIndicator
1553
+ },
1554
+ item.id
1555
+ )) })
1556
+ ]
1557
+ }
1558
+ ),
1559
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1560
+ "div",
1561
+ {
1562
+ className: listClassName,
1563
+ style: listClassName ? listStyle : { ...defaults.list, ...listStyle },
1564
+ children: [
1565
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1566
+ "div",
1567
+ {
1568
+ className: headerClassName,
1569
+ style: headerClassName ? headerStyle : { ...defaults.header, ...headerStyle },
1570
+ children: outputTitle
1571
+ }
1572
+ ),
1573
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: defaults.scroll, children: outputs?.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1574
+ MatrixItemRow,
1575
+ {
1576
+ item,
1577
+ type: "output",
1578
+ active: item.ti === si,
1579
+ showChannels,
1580
+ onSelect: () => handleTie(item.id),
1581
+ onToggleVideoMute: () => handleToggleVideoMute("output", item.id),
1582
+ itemClassName,
1583
+ itemStyle,
1584
+ itemActiveClassName,
1585
+ itemActiveStyle,
1586
+ itemDisabledClassName,
1587
+ vmButtonClassName,
1588
+ vmButtonActiveClassName,
1589
+ renderIoIndicator,
1590
+ renderSignalIndicator
1591
+ },
1592
+ item.id
1593
+ )) })
1594
+ ]
1595
+ }
1596
+ )
1597
+ ]
1598
+ }
1599
+ );
1600
+ }
1136
1601
  // Annotate the CommonJS export names for ESM import in node:
1137
1602
  0 && (module.exports = {
1138
1603
  CrisButton,
1604
+ CrisCoDebug,
1605
+ CrisCoMatrixListsTie,
1139
1606
  CrisGauge,
1140
1607
  CrisOfflinePage,
1141
1608
  CrisSlider,