@imperosoft/cris-webui-components 1.1.2-beta.12 → 1.1.2-beta.14

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.mjs CHANGED
@@ -100,6 +100,8 @@ function CrisButton({
100
100
  const pressedRef = useRef(false);
101
101
  const touchingRef = useRef(false);
102
102
  const touchStartedHereRef = useRef(false);
103
+ const touchStartYRef = useRef(0);
104
+ const touchMovedRef = useRef(false);
103
105
  const feedbackJoin = joinFeedback ?? join;
104
106
  const feedback = useDigital(feedbackJoin ?? 0);
105
107
  const enabledJoin = useDigital(joinEnable ?? 0);
@@ -182,22 +184,34 @@ function CrisButton({
182
184
  dSet(join, false);
183
185
  }
184
186
  };
185
- const handleTouchStart = () => {
187
+ const SCROLL_THRESHOLD = 8;
188
+ const handleTouchStart = (e) => {
186
189
  log("handleTouchStart");
187
190
  touchStart();
188
191
  touchingRef.current = true;
189
192
  touchStartedHereRef.current = true;
193
+ touchMovedRef.current = false;
194
+ touchStartYRef.current = e.touches[0]?.clientY ?? 0;
195
+ };
196
+ const handleTouchMove = (e) => {
197
+ if (touchMovedRef.current) return;
198
+ const dy = Math.abs((e.touches[0]?.clientY ?? 0) - touchStartYRef.current);
199
+ if (dy > SCROLL_THRESHOLD) {
200
+ touchMovedRef.current = true;
201
+ log("touchMove: scroll detected, dy:", dy);
202
+ }
190
203
  };
191
204
  const handleTouchEnd = () => {
192
- log("handleTouchEnd", { touchStartedHereRef: touchStartedHereRef.current });
205
+ log("handleTouchEnd", { touchStartedHere: touchStartedHereRef.current, moved: touchMovedRef.current });
193
206
  touchEnd();
194
207
  touchingRef.current = true;
195
- if (touchStartedHereRef.current) {
208
+ if (touchStartedHereRef.current && !touchMovedRef.current) {
196
209
  touchStartedHereRef.current = false;
197
210
  handlePress();
198
211
  handleRelease();
199
212
  } else {
200
- log("SKIPPED: touch did not start here");
213
+ touchStartedHereRef.current = false;
214
+ log("SKIPPED: touch moved or did not start here");
201
215
  }
202
216
  };
203
217
  const handleTouchCancel = () => {
@@ -205,6 +219,7 @@ function CrisButton({
205
219
  touchEnd();
206
220
  touchingRef.current = true;
207
221
  touchStartedHereRef.current = false;
222
+ touchMovedRef.current = false;
208
223
  };
209
224
  const handleMouseDown = () => {
210
225
  if (isTouchActive() || touchingRef.current) return;
@@ -305,7 +320,7 @@ function CrisButton({
305
320
  cursor: suppressKeyClicks ? "default" : "pointer",
306
321
  position: isFreePositioned ? void 0 : "relative",
307
322
  overflow: isFreePositioned ? void 0 : "hidden",
308
- touchAction: "pan-y",
323
+ touchAction: "pan-x pan-y",
309
324
  userSelect: "none",
310
325
  WebkitUserSelect: "none"
311
326
  },
@@ -313,6 +328,7 @@ function CrisButton({
313
328
  onMouseUp: handleMouseUp,
314
329
  onMouseLeave: handleMouseLeave,
315
330
  onTouchStart: handleTouchStart,
331
+ onTouchMove: handleTouchMove,
316
332
  onTouchEnd: handleTouchEnd,
317
333
  onTouchCancel: handleTouchCancel,
318
334
  children: [
@@ -1294,12 +1310,25 @@ function CrisCoDebug({
1294
1310
  // src/components/CrisCoMatrixListsTie.tsx
1295
1311
  import { useCustomObject as useCustomObject2, useCustomObjectSend as useCustomObjectSend2 } from "@imperosoft/cris-webui-ch5-core";
1296
1312
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1313
+ var colors = {
1314
+ itemBg: "#4f5152",
1315
+ itemActiveBg: "#007ca0",
1316
+ vmActiveBg: "#dc2626",
1317
+ text: "#ffffff",
1318
+ headerText: "#6b7280",
1319
+ ioOn: "#4caf50",
1320
+ ioOff: "#f44336",
1321
+ sgOn: "#2196f3",
1322
+ sgOff: "#666666"
1323
+ };
1297
1324
  var defaults = {
1298
1325
  container: {
1299
1326
  display: "flex",
1300
1327
  flexDirection: "row",
1301
- gap: 8,
1302
- height: "100%"
1328
+ gap: "1.5rem",
1329
+ padding: "1rem 2rem",
1330
+ height: "100%",
1331
+ width: "100%"
1303
1332
  },
1304
1333
  list: {
1305
1334
  flex: 1,
@@ -1309,57 +1338,125 @@ var defaults = {
1309
1338
  minHeight: 0
1310
1339
  },
1311
1340
  header: {
1312
- fontSize: 13,
1313
- fontWeight: 600,
1314
- padding: "6px 10px",
1341
+ fontSize: "1.5em",
1342
+ fontWeight: 700,
1343
+ padding: "0.5rem 0.75rem",
1315
1344
  textTransform: "uppercase",
1316
- opacity: 0.6,
1317
- flexShrink: 0
1345
+ letterSpacing: "0.05em",
1346
+ color: colors.headerText,
1347
+ flexShrink: 0,
1348
+ textAlign: "center"
1318
1349
  },
1319
1350
  scroll: {
1320
1351
  flex: 1,
1321
1352
  minHeight: 0,
1322
1353
  overflow: "auto",
1354
+ scrollbarWidth: "none",
1323
1355
  WebkitOverflowScrolling: "touch",
1324
1356
  display: "flex",
1325
1357
  flexDirection: "column",
1326
- gap: 2
1358
+ gap: "0.15rem"
1327
1359
  },
1328
1360
  item: {
1329
1361
  display: "flex",
1330
- alignItems: "center",
1331
- gap: 6,
1332
- padding: "6px 10px",
1333
- minHeight: 40,
1362
+ alignItems: "stretch",
1363
+ gap: "0.5rem",
1364
+ padding: "0 0.4rem 0 0",
1365
+ minHeight: "3.7rem",
1334
1366
  cursor: "pointer",
1335
- userSelect: "none"
1367
+ userSelect: "none",
1368
+ background: colors.itemBg,
1369
+ borderRadius: "0.5rem",
1370
+ transition: "background 0.15s"
1371
+ },
1372
+ itemActive: {
1373
+ background: colors.itemActiveBg
1374
+ },
1375
+ itemBtn: {
1376
+ flex: 1,
1377
+ minWidth: 0,
1378
+ background: "transparent",
1379
+ border: "none",
1380
+ padding: "0.5rem 0.9rem",
1381
+ textAlign: "left",
1382
+ color: colors.text,
1383
+ height: "100%",
1384
+ borderRadius: "0.5rem",
1385
+ cursor: "pointer"
1386
+ },
1387
+ itemBtnInner: {
1388
+ display: "flex",
1389
+ alignItems: "center",
1390
+ gap: "0.4rem",
1391
+ width: "100%"
1392
+ },
1393
+ channelNum: {
1394
+ flexShrink: 0,
1395
+ opacity: 0.6,
1396
+ minWidth: "1.7em",
1397
+ textAlign: "right",
1398
+ fontWeight: 400,
1399
+ marginRight: "0.4em"
1336
1400
  },
1337
1401
  itemLabel: {
1338
1402
  flex: 1,
1339
- fontSize: 13,
1403
+ fontSize: "1.4em",
1404
+ fontWeight: 700,
1340
1405
  whiteSpace: "nowrap",
1341
1406
  overflow: "hidden",
1342
- textOverflow: "ellipsis"
1407
+ textOverflow: "ellipsis",
1408
+ color: colors.text
1343
1409
  },
1344
1410
  indicators: {
1345
1411
  display: "flex",
1346
- gap: 4,
1412
+ gap: "0.25rem",
1347
1413
  alignItems: "center"
1348
1414
  },
1349
1415
  indicator: {
1350
- width: 8,
1351
- height: 8,
1416
+ width: "1rem",
1417
+ height: "1rem",
1352
1418
  borderRadius: "50%",
1353
1419
  flexShrink: 0
1420
+ },
1421
+ vmBtn: {
1422
+ flexShrink: 0,
1423
+ alignSelf: "stretch",
1424
+ display: "flex",
1425
+ alignItems: "center",
1426
+ background: colors.itemBg,
1427
+ color: colors.text,
1428
+ border: "none",
1429
+ borderRadius: "0.4rem",
1430
+ padding: "0 0.6rem",
1431
+ margin: "0.3rem 0.3rem 0.3rem 0",
1432
+ fontSize: "0.85em",
1433
+ fontWeight: 700,
1434
+ cursor: "pointer",
1435
+ transition: "background 0.15s"
1436
+ },
1437
+ vmBtnActive: {
1438
+ background: colors.vmActiveBg,
1439
+ color: colors.text
1354
1440
  }
1355
1441
  };
1442
+ var SCROLLBAR_CSS = `
1443
+ .cris-co-matrix-scroll::-webkit-scrollbar { display: none; }
1444
+ `;
1445
+ var scrollbarStyleInjected = false;
1446
+ function injectScrollbarStyle() {
1447
+ if (scrollbarStyleInjected) return;
1448
+ scrollbarStyleInjected = true;
1449
+ const style = document.createElement("style");
1450
+ style.textContent = SCROLLBAR_CSS;
1451
+ document.head.appendChild(style);
1452
+ }
1356
1453
  function DefaultIoIndicator({ on }) {
1357
1454
  return /* @__PURE__ */ jsx8(
1358
1455
  "div",
1359
1456
  {
1360
1457
  style: {
1361
1458
  ...defaults.indicator,
1362
- backgroundColor: on ? "#4caf50" : "#f44336"
1459
+ backgroundColor: on ? colors.ioOn : colors.ioOff
1363
1460
  },
1364
1461
  title: on ? "Online" : "Offline"
1365
1462
  }
@@ -1371,7 +1468,7 @@ function DefaultSignalIndicator({ on }) {
1371
1468
  {
1372
1469
  style: {
1373
1470
  ...defaults.indicator,
1374
- backgroundColor: on ? "#2196f3" : "#666"
1471
+ backgroundColor: on ? colors.sgOn : colors.sgOff
1375
1472
  },
1376
1473
  title: on ? "Signal detected" : "No signal"
1377
1474
  }
@@ -1397,18 +1494,19 @@ function MatrixItemRow({
1397
1494
  }) {
1398
1495
  const isActive = active;
1399
1496
  const isEnabled = item.sl.en;
1497
+ const useDefaults = !itemClassName;
1400
1498
  const classes = [
1401
1499
  "cris-co-matrix-item",
1402
1500
  itemClassName,
1403
1501
  isActive && (itemActiveClassName || "active"),
1404
1502
  !isEnabled && (itemDisabledClassName || "disabled")
1405
1503
  ].filter(Boolean).join(" ");
1406
- const computedStyle = itemClassName ? { ...itemStyleProp } : {
1504
+ const computedStyle = useDefaults ? {
1407
1505
  ...defaults.item,
1408
1506
  ...itemStyleProp,
1409
- ...isActive ? itemActiveStyle : void 0,
1507
+ ...isActive ? { ...defaults.itemActive, ...itemActiveStyle } : void 0,
1410
1508
  opacity: isEnabled ? 1 : 0.4
1411
- };
1509
+ } : { ...itemStyleProp };
1412
1510
  return /* @__PURE__ */ jsxs7("div", { className: classes, style: computedStyle, children: [
1413
1511
  /* @__PURE__ */ jsx8(
1414
1512
  CrisButton,
@@ -1416,19 +1514,40 @@ function MatrixItemRow({
1416
1514
  selected: isActive,
1417
1515
  enabled: isEnabled,
1418
1516
  onPress: onSelect,
1419
- className: `cris-co-matrix-item-btn ${itemActiveClassName ?? ""}`,
1420
- classActive: itemActiveClassName,
1421
- children: /* @__PURE__ */ jsxs7("div", { style: { display: "flex", alignItems: "center", gap: 6, width: "100%" }, children: [
1422
- showChannels && /* @__PURE__ */ jsx8("span", { className: "cris-co-matrix-ch", style: { flexShrink: 0, opacity: 0.6 }, children: item.id }),
1517
+ className: itemClassName ? `cris-co-matrix-item-btn ${itemActiveClassName ?? ""}` : void 0,
1518
+ classActive: itemClassName ? itemActiveClassName : void 0,
1519
+ children: useDefaults ? /* @__PURE__ */ jsxs7("div", { style: defaults.itemBtnInner, children: [
1520
+ showChannels && /* @__PURE__ */ jsx8("span", { className: "cris-co-matrix-ch", style: defaults.channelNum, children: item.id }),
1423
1521
  /* @__PURE__ */ jsx8("span", { style: defaults.itemLabel, children: item.lb || `${type === "input" ? "Input" : "Output"} ${item.id}` }),
1424
1522
  /* @__PURE__ */ jsxs7("div", { style: defaults.indicators, children: [
1425
1523
  item.io.vs && (renderIoIndicator ? renderIoIndicator(item.io.on) : /* @__PURE__ */ jsx8(DefaultIoIndicator, { on: item.io.on })),
1426
1524
  item.sg.vs && (renderSignalIndicator ? renderSignalIndicator(item.sg.on) : /* @__PURE__ */ jsx8(DefaultSignalIndicator, { on: item.sg.on }))
1427
1525
  ] })
1526
+ ] }) : /* @__PURE__ */ jsxs7("div", { style: { display: "flex", alignItems: "center", gap: "0.4rem", width: "100%" }, children: [
1527
+ showChannels && /* @__PURE__ */ jsx8("span", { className: "cris-co-matrix-ch", style: { flexShrink: 0, opacity: 0.6 }, children: item.id }),
1528
+ /* @__PURE__ */ jsx8("span", { style: { flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, children: item.lb || `${type === "input" ? "Input" : "Output"} ${item.id}` }),
1529
+ /* @__PURE__ */ jsxs7("div", { style: defaults.indicators, children: [
1530
+ item.io.vs && (renderIoIndicator ? renderIoIndicator(item.io.on) : /* @__PURE__ */ jsx8(DefaultIoIndicator, { on: item.io.on })),
1531
+ item.sg.vs && (renderSignalIndicator ? renderSignalIndicator(item.sg.on) : /* @__PURE__ */ jsx8(DefaultSignalIndicator, { on: item.sg.on }))
1532
+ ] })
1428
1533
  ] })
1429
1534
  }
1430
1535
  ),
1431
- item.vm.vs && /* @__PURE__ */ jsx8(
1536
+ item.vm.vs && (useDefaults && !vmButtonClassName ? /* @__PURE__ */ jsx8("div", { style: {
1537
+ ...defaults.vmBtn,
1538
+ ...item.vm.on ? defaults.vmBtnActive : void 0,
1539
+ opacity: item.vm.en ? 1 : 0.4,
1540
+ pointerEvents: item.vm.en ? "auto" : "none"
1541
+ }, children: /* @__PURE__ */ jsx8(
1542
+ CrisButton,
1543
+ {
1544
+ selected: item.vm.on,
1545
+ enabled: item.vm.en,
1546
+ text: vmText,
1547
+ onPress: onToggleVideoMute,
1548
+ showLocalFeedback: false
1549
+ }
1550
+ ) }) : /* @__PURE__ */ jsx8(
1432
1551
  CrisButton,
1433
1552
  {
1434
1553
  selected: item.vm.on,
@@ -1438,7 +1557,7 @@ function MatrixItemRow({
1438
1557
  className: vmButtonClassName,
1439
1558
  classActive: vmButtonActiveClassName
1440
1559
  }
1441
- )
1560
+ ))
1442
1561
  ] });
1443
1562
  }
1444
1563
  function CrisCoMatrixListsTie({
@@ -1465,6 +1584,7 @@ function CrisCoMatrixListsTie({
1465
1584
  }) {
1466
1585
  const matrix = useCustomObject2(oid);
1467
1586
  const send = useCustomObjectSend2();
1587
+ injectScrollbarStyle();
1468
1588
  if (!matrix) return null;
1469
1589
  const { si, ip: inputs, op: outputs } = matrix;
1470
1590
  const handleSelectInput = (id) => {
@@ -1496,7 +1616,7 @@ function CrisCoMatrixListsTie({
1496
1616
  children: inputTitle
1497
1617
  }
1498
1618
  ),
1499
- /* @__PURE__ */ jsx8("div", { style: defaults.scroll, children: inputs?.map((item) => /* @__PURE__ */ jsx8(
1619
+ /* @__PURE__ */ jsx8("div", { className: "cris-co-matrix-scroll", style: defaults.scroll, children: inputs?.map((item) => /* @__PURE__ */ jsx8(
1500
1620
  MatrixItemRow,
1501
1621
  {
1502
1622
  item,
@@ -1535,7 +1655,7 @@ function CrisCoMatrixListsTie({
1535
1655
  children: outputTitle
1536
1656
  }
1537
1657
  ),
1538
- /* @__PURE__ */ jsx8("div", { style: defaults.scroll, children: outputs?.map((item) => /* @__PURE__ */ jsx8(
1658
+ /* @__PURE__ */ jsx8("div", { className: "cris-co-matrix-scroll", style: defaults.scroll, children: outputs?.map((item) => /* @__PURE__ */ jsx8(
1539
1659
  MatrixItemRow,
1540
1660
  {
1541
1661
  item,