@imperosoft/cris-webui-components 1.1.2-beta.1 → 1.1.2-beta.2

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.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode } from 'react';
2
+ import { ReactNode, CSSProperties } from 'react';
3
3
 
4
4
  interface CrisButtonProps {
5
5
  /** Digital join for press action */
@@ -36,12 +36,18 @@ interface CrisButtonProps {
36
36
  iconClassActive?: string;
37
37
  /** Icon inline style when active (merged with iconStyle when button is active) */
38
38
  iconStyleActive?: React.CSSProperties;
39
+ /** External selected/active state (for controlled mode without joins) */
40
+ selected?: boolean;
39
41
  /** Show controller feedback styling */
40
42
  showControlFeedback?: boolean;
41
43
  /** Show local press feedback styling */
42
44
  showLocalFeedback?: boolean;
43
45
  /** Suppress click actions (display only) */
44
46
  suppressKeyClicks?: boolean;
47
+ /** External visible state (for controlled mode without joinVisible) */
48
+ visible?: boolean;
49
+ /** External enabled state (for controlled mode without joinEnable) */
50
+ enabled?: boolean;
45
51
  /** Smart object ID (for smarts instead of joins) */
46
52
  smartId?: number;
47
53
  /** Custom class names */
@@ -61,7 +67,7 @@ interface CrisButtonProps {
61
67
  /** Enable debug logging for this button */
62
68
  debug?: boolean;
63
69
  }
64
- declare function CrisButton({ join, joinFeedback, joinEnable, joinVisible, text, textPressed, textSelected, icon, iconName, iconClass, iconSize, iconContainerSize, iconStyle, iconPosition, iconNameActive, iconClassActive, iconStyleActive, showControlFeedback, showLocalFeedback, suppressKeyClicks, smartId, className, classActive, classPressed, classDisabled, children, onPress, onRelease, debug, }: CrisButtonProps): react_jsx_runtime.JSX.Element | null;
70
+ declare function CrisButton({ join, joinFeedback, joinEnable, joinVisible, text, textPressed, textSelected, icon, iconName, iconClass, iconSize, iconContainerSize, iconStyle, iconPosition, iconNameActive, iconClassActive, iconStyleActive, selected, showControlFeedback, showLocalFeedback, suppressKeyClicks, visible, enabled, smartId, className, classActive, classPressed, classDisabled, children, onPress, onRelease, debug, }: CrisButtonProps): react_jsx_runtime.JSX.Element | null;
65
71
 
66
72
  interface CrisTextProps {
67
73
  /** Serial join for indirect text */
@@ -256,6 +262,58 @@ interface CrisOfflinePageProps {
256
262
  }
257
263
  declare function CrisOfflinePage({ processorHost: processorHostProp, hasAuthToken, isDevMode, isVC4, isDeployedOnProcessor, wsPort, showDebugInfo, loginRedirectDelay, loginPath, retryCountdown: retryCountdownInit, className, }: CrisOfflinePageProps): react_jsx_runtime.JSX.Element;
258
264
 
265
+ /** Shape of a single module from the backend */
266
+ interface DebugModule {
267
+ id: string;
268
+ lb: string;
269
+ tp: string;
270
+ md: {
271
+ vs: boolean;
272
+ on: boolean;
273
+ };
274
+ cm: {
275
+ vs: boolean;
276
+ on: boolean;
277
+ };
278
+ et: {
279
+ vs: boolean;
280
+ on: boolean;
281
+ };
282
+ rs: {
283
+ vs: boolean;
284
+ on: boolean;
285
+ };
286
+ vs: boolean;
287
+ en: boolean;
288
+ }
289
+ interface CrisCoDebugProps {
290
+ /** Custom object ID (default: "__DBG__") */
291
+ oid?: string;
292
+ /** Optional title */
293
+ title?: string;
294
+ /** Container className */
295
+ className?: string;
296
+ /** Container style */
297
+ style?: CSSProperties;
298
+ /** Item className */
299
+ itemClassName?: string;
300
+ /** Item style */
301
+ itemStyle?: CSSProperties;
302
+ /** Button className for Mod/Com buttons */
303
+ buttonClassName?: string;
304
+ /** Button active className for Mod/Com buttons */
305
+ buttonActiveClassName?: string;
306
+ /** Custom icon for Ethernet connected */
307
+ iconEthOn?: ReactNode;
308
+ /** Custom icon for Ethernet disconnected */
309
+ iconEthOff?: ReactNode;
310
+ /** Custom icon for RS232 connected */
311
+ iconRs232On?: ReactNode;
312
+ /** Custom icon for RS232 disconnected */
313
+ iconRs232Off?: ReactNode;
314
+ }
315
+ declare function CrisCoDebug({ oid, title, className, style, itemClassName, itemStyle, buttonClassName, buttonActiveClassName, iconEthOn, iconEthOff, iconRs232On, iconRs232Off, }: CrisCoDebugProps): react_jsx_runtime.JSX.Element | null;
316
+
259
317
  /**
260
318
  * Icon configuration and utilities for CRIS components
261
319
  *
@@ -306,4 +364,4 @@ declare function getIconUrl(name: string): string;
306
364
  */
307
365
  declare function getIconFilter(active: boolean): string | undefined;
308
366
 
309
- export { CrisButton, type CrisButtonProps, CrisGauge, type CrisGaugeProps, CrisOfflinePage, type CrisOfflinePageProps, CrisSlider, type CrisSliderProps, CrisSpinner, type CrisSpinnerProps, CrisText, type CrisTextProps, type IconConfig, type SpinnerSpeed, configureIcons, getIconConfig, getIconFilter, getIconUrl };
367
+ export { CrisButton, type CrisButtonProps, CrisCoDebug, type CrisCoDebugProps, CrisGauge, type CrisGaugeProps, CrisOfflinePage, type CrisOfflinePageProps, CrisSlider, type CrisSliderProps, CrisSpinner, type CrisSpinnerProps, CrisText, type CrisTextProps, type DebugModule, type IconConfig, type SpinnerSpeed, configureIcons, getIconConfig, getIconFilter, getIconUrl };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode } from 'react';
2
+ import { ReactNode, CSSProperties } from 'react';
3
3
 
4
4
  interface CrisButtonProps {
5
5
  /** Digital join for press action */
@@ -36,12 +36,18 @@ interface CrisButtonProps {
36
36
  iconClassActive?: string;
37
37
  /** Icon inline style when active (merged with iconStyle when button is active) */
38
38
  iconStyleActive?: React.CSSProperties;
39
+ /** External selected/active state (for controlled mode without joins) */
40
+ selected?: boolean;
39
41
  /** Show controller feedback styling */
40
42
  showControlFeedback?: boolean;
41
43
  /** Show local press feedback styling */
42
44
  showLocalFeedback?: boolean;
43
45
  /** Suppress click actions (display only) */
44
46
  suppressKeyClicks?: boolean;
47
+ /** External visible state (for controlled mode without joinVisible) */
48
+ visible?: boolean;
49
+ /** External enabled state (for controlled mode without joinEnable) */
50
+ enabled?: boolean;
45
51
  /** Smart object ID (for smarts instead of joins) */
46
52
  smartId?: number;
47
53
  /** Custom class names */
@@ -61,7 +67,7 @@ interface CrisButtonProps {
61
67
  /** Enable debug logging for this button */
62
68
  debug?: boolean;
63
69
  }
64
- declare function CrisButton({ join, joinFeedback, joinEnable, joinVisible, text, textPressed, textSelected, icon, iconName, iconClass, iconSize, iconContainerSize, iconStyle, iconPosition, iconNameActive, iconClassActive, iconStyleActive, showControlFeedback, showLocalFeedback, suppressKeyClicks, smartId, className, classActive, classPressed, classDisabled, children, onPress, onRelease, debug, }: CrisButtonProps): react_jsx_runtime.JSX.Element | null;
70
+ declare function CrisButton({ join, joinFeedback, joinEnable, joinVisible, text, textPressed, textSelected, icon, iconName, iconClass, iconSize, iconContainerSize, iconStyle, iconPosition, iconNameActive, iconClassActive, iconStyleActive, selected, showControlFeedback, showLocalFeedback, suppressKeyClicks, visible, enabled, smartId, className, classActive, classPressed, classDisabled, children, onPress, onRelease, debug, }: CrisButtonProps): react_jsx_runtime.JSX.Element | null;
65
71
 
66
72
  interface CrisTextProps {
67
73
  /** Serial join for indirect text */
@@ -256,6 +262,58 @@ interface CrisOfflinePageProps {
256
262
  }
257
263
  declare function CrisOfflinePage({ processorHost: processorHostProp, hasAuthToken, isDevMode, isVC4, isDeployedOnProcessor, wsPort, showDebugInfo, loginRedirectDelay, loginPath, retryCountdown: retryCountdownInit, className, }: CrisOfflinePageProps): react_jsx_runtime.JSX.Element;
258
264
 
265
+ /** Shape of a single module from the backend */
266
+ interface DebugModule {
267
+ id: string;
268
+ lb: string;
269
+ tp: string;
270
+ md: {
271
+ vs: boolean;
272
+ on: boolean;
273
+ };
274
+ cm: {
275
+ vs: boolean;
276
+ on: boolean;
277
+ };
278
+ et: {
279
+ vs: boolean;
280
+ on: boolean;
281
+ };
282
+ rs: {
283
+ vs: boolean;
284
+ on: boolean;
285
+ };
286
+ vs: boolean;
287
+ en: boolean;
288
+ }
289
+ interface CrisCoDebugProps {
290
+ /** Custom object ID (default: "__DBG__") */
291
+ oid?: string;
292
+ /** Optional title */
293
+ title?: string;
294
+ /** Container className */
295
+ className?: string;
296
+ /** Container style */
297
+ style?: CSSProperties;
298
+ /** Item className */
299
+ itemClassName?: string;
300
+ /** Item style */
301
+ itemStyle?: CSSProperties;
302
+ /** Button className for Mod/Com buttons */
303
+ buttonClassName?: string;
304
+ /** Button active className for Mod/Com buttons */
305
+ buttonActiveClassName?: string;
306
+ /** Custom icon for Ethernet connected */
307
+ iconEthOn?: ReactNode;
308
+ /** Custom icon for Ethernet disconnected */
309
+ iconEthOff?: ReactNode;
310
+ /** Custom icon for RS232 connected */
311
+ iconRs232On?: ReactNode;
312
+ /** Custom icon for RS232 disconnected */
313
+ iconRs232Off?: ReactNode;
314
+ }
315
+ declare function CrisCoDebug({ oid, title, className, style, itemClassName, itemStyle, buttonClassName, buttonActiveClassName, iconEthOn, iconEthOff, iconRs232On, iconRs232Off, }: CrisCoDebugProps): react_jsx_runtime.JSX.Element | null;
316
+
259
317
  /**
260
318
  * Icon configuration and utilities for CRIS components
261
319
  *
@@ -306,4 +364,4 @@ declare function getIconUrl(name: string): string;
306
364
  */
307
365
  declare function getIconFilter(active: boolean): string | undefined;
308
366
 
309
- export { CrisButton, type CrisButtonProps, CrisGauge, type CrisGaugeProps, CrisOfflinePage, type CrisOfflinePageProps, CrisSlider, type CrisSliderProps, CrisSpinner, type CrisSpinnerProps, CrisText, type CrisTextProps, type IconConfig, type SpinnerSpeed, configureIcons, getIconConfig, getIconFilter, getIconUrl };
367
+ export { CrisButton, type CrisButtonProps, CrisCoDebug, type CrisCoDebugProps, CrisGauge, type CrisGaugeProps, CrisOfflinePage, type CrisOfflinePageProps, CrisSlider, type CrisSliderProps, CrisSpinner, type CrisSpinnerProps, CrisText, type CrisTextProps, type DebugModule, type IconConfig, type SpinnerSpeed, configureIcons, getIconConfig, getIconFilter, getIconUrl };
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ 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,
24
25
  CrisGauge: () => CrisGauge,
25
26
  CrisOfflinePage: () => CrisOfflinePage,
26
27
  CrisSlider: () => CrisSlider,
@@ -108,9 +109,12 @@ function CrisButton({
108
109
  iconNameActive,
109
110
  iconClassActive,
110
111
  iconStyleActive,
112
+ selected,
111
113
  showControlFeedback = true,
112
114
  showLocalFeedback = true,
113
115
  suppressKeyClicks = false,
116
+ visible,
117
+ enabled,
114
118
  smartId,
115
119
  className = "",
116
120
  classActive = "",
@@ -134,11 +138,11 @@ function CrisButton({
134
138
  const touchStartedHereRef = (0, import_react.useRef)(false);
135
139
  const feedbackJoin = joinFeedback ?? join;
136
140
  const feedback = (0, import_cris_webui_ch5_core.useDigital)(feedbackJoin ?? 0);
137
- const enabled = (0, import_cris_webui_ch5_core.useDigital)(joinEnable ?? 0);
138
- const visible = (0, import_cris_webui_ch5_core.useDigital)(joinVisible ?? 0);
141
+ const enabledJoin = (0, import_cris_webui_ch5_core.useDigital)(joinEnable ?? 0);
142
+ const visibleJoin = (0, import_cris_webui_ch5_core.useDigital)(joinVisible ?? 0);
139
143
  const dSet = (0, import_cris_webui_ch5_core.useJoinsStore)((state) => state.dSet);
140
- const isEnabled = joinEnable == null ? true : enabled;
141
- const isVisible = joinVisible == null ? true : visible;
144
+ const isEnabled = enabled ?? (joinEnable == null ? true : enabledJoin);
145
+ const isVisible = visible ?? (joinVisible == null ? true : visibleJoin);
142
146
  (0, import_react.useEffect)(() => {
143
147
  log("visibility effect", { isVisible, pressedRef: pressedRef.current });
144
148
  if (!isVisible && pressedRef.current) {
@@ -161,7 +165,7 @@ function CrisButton({
161
165
  }
162
166
  };
163
167
  }, [join, smartId, dSet, log]);
164
- const hasControlFeedback = showControlFeedback && feedbackJoin != null && feedback;
168
+ const hasControlFeedback = showControlFeedback && (feedbackJoin != null && feedback || selected === true);
165
169
  const hasPressedFeedback = showLocalFeedback && pressed && isEnabled;
166
170
  const isActive = hasControlFeedback || hasPressedFeedback;
167
171
  let currentText = text ?? "";
@@ -1138,9 +1142,195 @@ function CrisOfflinePage({
1138
1142
  ] })
1139
1143
  ] }) });
1140
1144
  }
1145
+
1146
+ // src/components/CrisCoDebug.tsx
1147
+ var import_cris_webui_ch5_core7 = require("@imperosoft/cris-webui-ch5-core");
1148
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1149
+ var defaultStyles = {
1150
+ container: {
1151
+ display: "flex",
1152
+ flexDirection: "column",
1153
+ overflow: "auto",
1154
+ gap: 2
1155
+ },
1156
+ title: {
1157
+ fontSize: 14,
1158
+ fontWeight: 600,
1159
+ padding: "8px 12px",
1160
+ opacity: 0.7
1161
+ },
1162
+ item: {
1163
+ display: "flex",
1164
+ alignItems: "center",
1165
+ padding: "8px 12px",
1166
+ gap: 8,
1167
+ minHeight: 48
1168
+ },
1169
+ info: {
1170
+ flex: 1,
1171
+ minWidth: 0,
1172
+ overflow: "hidden"
1173
+ },
1174
+ moduleName: {
1175
+ fontSize: 14,
1176
+ fontWeight: 600,
1177
+ whiteSpace: "nowrap",
1178
+ overflow: "hidden",
1179
+ textOverflow: "ellipsis"
1180
+ },
1181
+ moduleType: {
1182
+ fontSize: 11,
1183
+ opacity: 0.5
1184
+ },
1185
+ icons: {
1186
+ display: "flex",
1187
+ gap: 4,
1188
+ alignItems: "center",
1189
+ minWidth: 56,
1190
+ justifyContent: "center"
1191
+ },
1192
+ buttons: {
1193
+ display: "flex",
1194
+ gap: 4,
1195
+ alignItems: "center"
1196
+ },
1197
+ iconBox: {
1198
+ width: 24,
1199
+ height: 24,
1200
+ display: "flex",
1201
+ alignItems: "center",
1202
+ justifyContent: "center",
1203
+ position: "relative"
1204
+ }
1205
+ };
1206
+ function ConnectionIcon({ on, type }) {
1207
+ const label = type === "eth" ? "ETH" : "RS";
1208
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1209
+ "div",
1210
+ {
1211
+ style: {
1212
+ ...defaultStyles.iconBox,
1213
+ opacity: on ? 1 : 0.4
1214
+ },
1215
+ title: `${type === "eth" ? "Ethernet" : "RS232"}: ${on ? "Connected" : "Disconnected"}`,
1216
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", children: [
1217
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "1", y: "4", width: "18", height: "12", rx: "2", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
1218
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("text", { x: "10", y: "12.5", textAnchor: "middle", fontSize: "7", fontWeight: "bold", fill: "currentColor", children: label }),
1219
+ 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: [
1220
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "16", cy: "5", r: "3.5", fill: "#f44336", stroke: "none" }),
1221
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "14", y1: "3", x2: "18", y2: "7", stroke: "white", strokeWidth: "1.5" })
1222
+ ] })
1223
+ ] })
1224
+ }
1225
+ );
1226
+ }
1227
+ function DebugModuleItem({
1228
+ module: module2,
1229
+ onAction,
1230
+ itemClassName,
1231
+ itemStyle,
1232
+ buttonClassName,
1233
+ buttonActiveClassName,
1234
+ iconEthOn,
1235
+ iconEthOff,
1236
+ iconRs232On,
1237
+ iconRs232Off
1238
+ }) {
1239
+ const name = module2.lb ? `${module2.id} (${module2.lb})` : module2.id;
1240
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1241
+ "div",
1242
+ {
1243
+ className: itemClassName,
1244
+ style: itemClassName ? itemStyle : { ...defaultStyles.item, ...itemStyle },
1245
+ children: [
1246
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: defaultStyles.info, children: [
1247
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: defaultStyles.moduleName, children: name }),
1248
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: defaultStyles.moduleType, children: module2.tp })
1249
+ ] }),
1250
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: defaultStyles.icons, children: [
1251
+ module2.et.vs && (iconEthOn && iconEthOff ? module2.et.on ? iconEthOn : iconEthOff : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConnectionIcon, { on: module2.et.on, type: "eth" })),
1252
+ module2.rs.vs && (iconRs232On && iconRs232Off ? module2.rs.on ? iconRs232On : iconRs232Off : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConnectionIcon, { on: module2.rs.on, type: "rs232" }))
1253
+ ] }),
1254
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: defaultStyles.buttons, children: [
1255
+ module2.md.vs && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1256
+ CrisButton,
1257
+ {
1258
+ selected: module2.md.on,
1259
+ text: "Mod",
1260
+ className: buttonClassName,
1261
+ classActive: buttonActiveClassName,
1262
+ onPress: () => onAction("toggleMod", module2.id)
1263
+ }
1264
+ ),
1265
+ module2.cm.vs && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1266
+ CrisButton,
1267
+ {
1268
+ selected: module2.cm.on,
1269
+ text: "Com",
1270
+ className: buttonClassName,
1271
+ classActive: buttonActiveClassName,
1272
+ onPress: () => onAction("toggleCom", module2.id)
1273
+ }
1274
+ )
1275
+ ] })
1276
+ ]
1277
+ }
1278
+ );
1279
+ }
1280
+ function CrisCoDebug({
1281
+ oid = "__DBG__",
1282
+ title,
1283
+ className,
1284
+ style,
1285
+ itemClassName,
1286
+ itemStyle,
1287
+ buttonClassName,
1288
+ buttonActiveClassName,
1289
+ iconEthOn,
1290
+ iconEthOff,
1291
+ iconRs232On,
1292
+ iconRs232Off
1293
+ }) {
1294
+ const modules = (0, import_cris_webui_ch5_core7.useCustomObject)(oid);
1295
+ const send = (0, import_cris_webui_ch5_core7.useCustomObjectSend)();
1296
+ const handleAction = (action, id) => {
1297
+ send(oid, { action, id });
1298
+ };
1299
+ if (!modules || modules.length === 0) {
1300
+ return null;
1301
+ }
1302
+ const visibleModules = modules.filter((m) => m.vs);
1303
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1304
+ "div",
1305
+ {
1306
+ className,
1307
+ style: className ? style : { ...defaultStyles.container, ...style },
1308
+ children: [
1309
+ title && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: defaultStyles.title, children: title }),
1310
+ visibleModules.map((module2) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1311
+ DebugModuleItem,
1312
+ {
1313
+ module: module2,
1314
+ onAction: handleAction,
1315
+ itemClassName,
1316
+ itemStyle,
1317
+ buttonClassName,
1318
+ buttonActiveClassName,
1319
+ iconEthOn,
1320
+ iconEthOff,
1321
+ iconRs232On,
1322
+ iconRs232Off
1323
+ },
1324
+ module2.id
1325
+ ))
1326
+ ]
1327
+ }
1328
+ );
1329
+ }
1141
1330
  // Annotate the CommonJS export names for ESM import in node:
1142
1331
  0 && (module.exports = {
1143
1332
  CrisButton,
1333
+ CrisCoDebug,
1144
1334
  CrisGauge,
1145
1335
  CrisOfflinePage,
1146
1336
  CrisSlider,