@procaaso/alphinity-ui-components 1.10.0 → 1.12.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/dist/index.d.cts CHANGED
@@ -1,16 +1,16 @@
1
- import * as react from 'react';
2
- import react__default from 'react';
1
+ import * as React$1 from 'react';
2
+ import React__default from 'react';
3
3
  import * as _emotion_styled from '@emotion/styled';
4
4
  import * as _emotion_react from '@emotion/react';
5
5
  import * as _mui_system from '@mui/system';
6
6
  import * as _mui_material from '@mui/material';
7
7
  import * as _mui_material_OverridableComponent from '@mui/material/OverridableComponent';
8
8
 
9
- interface ButtonProps extends react__default.ButtonHTMLAttributes<HTMLButtonElement> {
9
+ interface ButtonProps extends React__default.ButtonHTMLAttributes<HTMLButtonElement> {
10
10
  variant?: 'primary' | 'secondary';
11
- children: react__default.ReactNode;
11
+ children: React__default.ReactNode;
12
12
  }
13
- declare const Button: react__default.FC<ButtonProps>;
13
+ declare const Button: React__default.FC<ButtonProps>;
14
14
 
15
15
  interface SelectorOption {
16
16
  /** Unique value for the option */
@@ -22,7 +22,7 @@ interface SelectorOption {
22
22
  /** Optional description for tooltip or additional context */
23
23
  description?: string;
24
24
  }
25
- interface SelectorProps extends Omit<react__default.HTMLAttributes<HTMLDivElement>, 'onChange'> {
25
+ interface SelectorProps extends Omit<React__default.HTMLAttributes<HTMLDivElement>, 'onChange'> {
26
26
  /** Currently selected value */
27
27
  value: string;
28
28
  /** Callback when selection changes */
@@ -42,12 +42,17 @@ interface SelectorProps extends Omit<react__default.HTMLAttributes<HTMLDivElemen
42
42
  /** Whether the dropdown should open upward */
43
43
  dropdownUp?: boolean;
44
44
  }
45
- declare const Selector: react__default.FC<SelectorProps>;
45
+ declare const Selector: React__default.FC<SelectorProps>;
46
46
 
47
47
  /**
48
- * Status levels for telemetry values
48
+ * Status levels for telemetry values.
49
+ *
50
+ * `unknown` marks a value the backend does not trust. OPC UA publishes this
51
+ * condition as StatusCode severity Bad. This library never derives `unknown`
52
+ * from a number or a threshold. This library only displays an `unknown`
53
+ * value that the backend has already published.
49
54
  */
50
- type TelemetryStatus$1 = 'normal' | 'warning' | 'alarm' | 'fault' | 'off';
55
+ type TelemetryStatus$1 = 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'unknown';
51
56
  /**
52
57
  * Marks a value as a maintenance force rather than a measured reading
53
58
  * (alphinity-tffi issue #3607, unit U11). A forced value is a deliberate
@@ -171,6 +176,7 @@ interface TelemetryBinding {
171
176
  alarm?: string;
172
177
  fault?: string;
173
178
  off?: string;
179
+ unknown?: string;
174
180
  };
175
181
  /** Display configuration */
176
182
  display?: {
@@ -225,7 +231,7 @@ interface ModeConfig {
225
231
  /** Precision for second setpoint */
226
232
  secondPrecision?: number;
227
233
  }
228
- interface ControlPanelProps extends react__default.HTMLAttributes<HTMLDivElement> {
234
+ interface ControlPanelProps extends React__default.HTMLAttributes<HTMLDivElement> {
229
235
  /** Panel title/identifier */
230
236
  title: string;
231
237
  /** Currently selected mode */
@@ -310,14 +316,26 @@ interface ControlPanelProps extends react__default.HTMLAttributes<HTMLDivElement
310
316
  /** Custom stop button text */
311
317
  stopButtonText?: string;
312
318
  }
313
- declare const ControlPanel: react__default.FC<ControlPanelProps>;
319
+ declare const ControlPanel: React__default.FC<ControlPanelProps>;
314
320
 
315
- interface StatusIndicatorProps extends react__default.HTMLAttributes<HTMLDivElement> {
316
- /** Status state determining color and behavior */
317
- status: 'off' | 'normal' | 'alarm' | 'warning' | 'active' | 'fault';
321
+ interface StatusIndicatorProps extends React__default.HTMLAttributes<HTMLDivElement> {
322
+ /**
323
+ * Status state determining color and behavior.
324
+ *
325
+ * `unknown` marks a value the backend does not trust. Set `unknown` only
326
+ * from a published bad-quality read. Do not derive `unknown` from a number
327
+ * or a threshold in this component.
328
+ */
329
+ status: 'off' | 'normal' | 'alarm' | 'warning' | 'active' | 'fault' | 'unknown';
318
330
  /** Size of the indicator */
319
331
  size?: 'small' | 'medium' | 'large';
320
- /** Animation behavior */
332
+ /**
333
+ * Animation behavior. Default is `none`.
334
+ *
335
+ * ISA-18.2 reserves blinking for an unacknowledged alarm. The `unknown`
336
+ * status does not clamp this prop to `none`. Pass `animation` only when
337
+ * the alarm state of the point needs it.
338
+ */
321
339
  animation?: 'none' | 'pulse' | 'blink' | 'flash';
322
340
  /** Label text to display next to indicator */
323
341
  label?: string;
@@ -327,6 +345,8 @@ interface StatusIndicatorProps extends react__default.HTMLAttributes<HTMLDivElem
327
345
  shape?: 'circle' | 'square' | 'diamond';
328
346
  /** Whether the indicator should have a 3D LED effect */
329
347
  led?: boolean;
348
+ /** Whether the indicator is rendered at all. When false, nothing is rendered. Defaults to true. */
349
+ visible?: boolean;
330
350
  /**
331
351
  * True when the underlying tag's state is a maintenance force, not a
332
352
  * measured reading (#3607, R19). Renders a small glyph badge, never a
@@ -344,9 +364,9 @@ interface StatusIndicatorProps extends react__default.HTMLAttributes<HTMLDivElem
344
364
  */
345
365
  realValue?: string;
346
366
  }
347
- declare const StatusIndicator: react__default.FC<StatusIndicatorProps>;
367
+ declare const StatusIndicator: React__default.FC<StatusIndicatorProps>;
348
368
 
349
- interface ValueEntryProps extends Omit<react__default.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
369
+ interface ValueEntryProps extends Omit<React__default.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
350
370
  /** Current value */
351
371
  value: number | string;
352
372
  /** Callback when value changes */
@@ -381,9 +401,9 @@ interface ValueEntryProps extends Omit<react__default.InputHTMLAttributes<HTMLIn
381
401
  */
382
402
  realValue?: number | string;
383
403
  }
384
- declare const ValueEntry: react__default.FC<ValueEntryProps>;
404
+ declare const ValueEntry: React__default.FC<ValueEntryProps>;
385
405
 
386
- interface LegacyValueEntryProps extends Omit<react__default.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
406
+ interface LegacyValueEntryProps extends Omit<React__default.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
387
407
  /** Current value */
388
408
  value: number | string;
389
409
  /** Callback when value changes */
@@ -415,7 +435,7 @@ interface LegacyValueEntryProps extends Omit<react__default.InputHTMLAttributes<
415
435
  */
416
436
  realValue?: number | string;
417
437
  }
418
- declare const LegacyValueEntry: react__default.FC<LegacyValueEntryProps>;
438
+ declare const LegacyValueEntry: React__default.FC<LegacyValueEntryProps>;
419
439
 
420
440
  interface NodeControlConfig {
421
441
  /** Node ID */
@@ -459,7 +479,7 @@ interface NodeControlConfig {
459
479
  /** Whether setpoint is read-only */
460
480
  readOnly?: boolean;
461
481
  }
462
- interface NodeControlsPanelProps extends react__default.HTMLAttributes<HTMLDivElement> {
482
+ interface NodeControlsPanelProps extends React__default.HTMLAttributes<HTMLDivElement> {
463
483
  /** Control configuration for the selected node */
464
484
  config: NodeControlConfig | null;
465
485
  /** Callback to close the panel */
@@ -478,7 +498,7 @@ interface NodeControlsPanelProps extends react__default.HTMLAttributes<HTMLDivEl
478
498
  * - Clear visual feedback
479
499
  * - Bottom or side slide-in animation
480
500
  */
481
- declare const NodeControlsPanel: react__default.FC<NodeControlsPanelProps>;
501
+ declare const NodeControlsPanel: React__default.FC<NodeControlsPanelProps>;
482
502
 
483
503
  /**
484
504
  * A custom action button rendered in the device control panel (e.g. Tare, Zero).
@@ -585,8 +605,12 @@ interface ControlState {
585
605
  isRunning?: boolean;
586
606
  /** Is device in alarm state? */
587
607
  hasAlarm?: boolean;
588
- /** Current status */
589
- status?: 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping';
608
+ /**
609
+ * Current status. `unknown` marks an untrusted read (OPC UA StatusCode
610
+ * severity Bad). This library never infers `unknown`; it only displays a
611
+ * value the backend has already published as `unknown`.
612
+ */
613
+ status?: 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping' | 'unknown';
590
614
  /** Status message */
591
615
  statusMessage?: string;
592
616
  /** Last command timestamp */
@@ -674,6 +698,7 @@ interface DeviceControlBinding {
674
698
  off?: string;
675
699
  starting?: string;
676
700
  stopping?: string;
701
+ unknown?: string;
677
702
  };
678
703
  };
679
704
  }
@@ -793,9 +818,9 @@ interface DeviceControlPanelProps {
793
818
  * its live values move, so the memo bails only on genuinely idle ticks - the
794
819
  * win is proportional to how often values are flat at display precision.
795
820
  */
796
- declare function DeviceControlPanelImpl({ binding, onClose, position, align, touchOptimized, compact, fontScale, maxHeight, maxWidth, toastDuration, onModeChange, onParameterChange, onParameterActivate, onStart, onStop, startPending, stopPending, onCustomAction, onOpenConfig, showConfigButton, onUndock, undockIcon, modeSelectionStyle, showBuiltInToast, embedded, }: DeviceControlPanelProps): react__default.JSX.Element | null;
821
+ declare function DeviceControlPanelImpl({ binding, onClose, position, align, touchOptimized, compact, fontScale, maxHeight, maxWidth, toastDuration, onModeChange, onParameterChange, onParameterActivate, onStart, onStop, startPending, stopPending, onCustomAction, onOpenConfig, showConfigButton, onUndock, undockIcon, modeSelectionStyle, showBuiltInToast, embedded, }: DeviceControlPanelProps): React__default.JSX.Element | null;
797
822
  /** Memo boundary - see DeviceControlPanelImpl doc comment (kiosk heap-leak fix). */
798
- declare const DeviceControlPanel: react__default.MemoExoticComponent<typeof DeviceControlPanelImpl>;
823
+ declare const DeviceControlPanel: React__default.MemoExoticComponent<typeof DeviceControlPanelImpl>;
799
824
 
800
825
  interface NumpadDialogProps {
801
826
  /** Whether the dialog is open */
@@ -844,7 +869,7 @@ interface NumpadDialogProps {
844
869
  * out-of-range values are rejected (never silently clamped). The field pre-fills
845
870
  * with the current value so an operator never blind-zeroes a live setpoint.
846
871
  */
847
- declare const NumpadDialog: react__default.FC<NumpadDialogProps>;
872
+ declare const NumpadDialog: React__default.FC<NumpadDialogProps>;
848
873
 
849
874
  type DisplayMode = 'standard' | 'dashboard';
850
875
  interface FullscreenContainerProps {
@@ -855,9 +880,9 @@ type OverlayTheme = 'tank' | 'pressure' | 'vessel' | 'flow';
855
880
  interface SVGLockedOverlayProps {
856
881
  svgX: number;
857
882
  svgY: number;
858
- children: react__default.ReactNode;
883
+ children: React__default.ReactNode;
859
884
  theme?: OverlayTheme;
860
- style?: react__default.CSSProperties;
885
+ style?: React__default.CSSProperties;
861
886
  className?: string;
862
887
  onClick?: () => void;
863
888
  containerSelector?: string;
@@ -929,7 +954,7 @@ interface EquipmentIndicatorProps {
929
954
  color: string;
930
955
  label: string;
931
956
  size?: number;
932
- style?: react__default.CSSProperties;
957
+ style?: React__default.CSSProperties;
933
958
  className?: string;
934
959
  /**
935
960
  * True when this equipment's state is a maintenance force, not a measured
@@ -941,14 +966,14 @@ interface EquipmentIndicatorProps {
941
966
  interface FullscreenWorkspaceTab {
942
967
  label: string;
943
968
  value: string;
944
- content: react__default.ReactNode;
945
- }
946
- interface FullscreenWorkspaceProps extends react__default.HTMLAttributes<HTMLDivElement> {
947
- svgContent: react__default.ReactNode;
948
- overlays?: react__default.ReactNode;
949
- leftPanel?: react__default.ReactNode;
950
- rightPanel?: react__default.ReactNode;
951
- footer?: react__default.ReactNode;
969
+ content: React__default.ReactNode;
970
+ }
971
+ interface FullscreenWorkspaceProps extends React__default.HTMLAttributes<HTMLDivElement> {
972
+ svgContent: React__default.ReactNode;
973
+ overlays?: React__default.ReactNode;
974
+ leftPanel?: React__default.ReactNode;
975
+ rightPanel?: React__default.ReactNode;
976
+ footer?: React__default.ReactNode;
952
977
  tabs?: FullscreenWorkspaceTab[];
953
978
  activeTab?: string;
954
979
  onTabChange?: (value: string) => void;
@@ -969,60 +994,60 @@ interface FullscreenWorkspaceProps extends react__default.HTMLAttributes<HTMLDiv
969
994
  zoomDisabled?: boolean;
970
995
  }
971
996
 
972
- declare const FullscreenContainer: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
997
+ declare const FullscreenContainer: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
973
998
  theme?: _emotion_react.Theme;
974
999
  } & FullscreenContainerProps, {}, {}>;
975
- declare const LeftPanel: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1000
+ declare const LeftPanel: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
976
1001
  theme?: _emotion_react.Theme;
977
1002
  } & {
978
1003
  collapsed: boolean;
979
1004
  }, {}, {}>;
980
- declare const RightPanel: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1005
+ declare const RightPanel: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
981
1006
  theme?: _emotion_react.Theme;
982
1007
  } & {
983
1008
  collapsed: boolean;
984
1009
  }, {}, {}>;
985
- declare const SVGArea: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1010
+ declare const SVGArea: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
986
1011
  theme?: _emotion_react.Theme;
987
1012
  }, {}, {}>;
988
- declare const LeftToggleButton: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
1013
+ declare const LeftToggleButton: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
989
1014
  theme?: _emotion_react.Theme;
990
1015
  } & {
991
1016
  collapsed: boolean;
992
1017
  }, {}, {}>;
993
- declare const RightToggleButton: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
1018
+ declare const RightToggleButton: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
994
1019
  theme?: _emotion_react.Theme;
995
1020
  } & {
996
1021
  collapsed: boolean;
997
1022
  }, {}, {}>;
998
- declare const DisplayModeToggle: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
1023
+ declare const DisplayModeToggle: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
999
1024
  theme?: _emotion_react.Theme;
1000
1025
  } & {
1001
1026
  mode: DisplayMode;
1002
1027
  }, {}, {}>;
1003
- declare const ZoomControls: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1028
+ declare const ZoomControls: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1004
1029
  theme?: _emotion_react.Theme;
1005
1030
  }, {}, {}>;
1006
- declare const ZoomButton: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
1031
+ declare const ZoomButton: _emotion_styled.StyledComponent<_mui_material.IconButtonOwnProps & Omit<_mui_material.ButtonBaseOwnProps, "classes"> & _mui_material_OverridableComponent.CommonProps & Omit<React$1.DetailedHTMLProps<React$1.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "children" | "className" | "disabled" | "style" | "tabIndex" | "color" | "size" | "sx" | "classes" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator"> & {
1007
1032
  theme?: _emotion_react.Theme;
1008
1033
  }, {}, {}>;
1009
- declare const FooterPanel: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1034
+ declare const FooterPanel: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1010
1035
  theme?: _emotion_react.Theme;
1011
1036
  }, {}, {}>;
1012
- declare const PanelTabs: _emotion_styled.StyledComponent<_mui_material.TabsOwnProps & _mui_material_OverridableComponent.CommonProps & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "variant" | "children" | "className" | "value" | "style" | "aria-label" | "aria-labelledby" | "onChange" | "sx" | "classes" | "action" | "allowScrollButtonsMobile" | "centered" | "indicatorColor" | "orientation" | "ScrollButtonComponent" | "scrollButtons" | "selectionFollowsFocus" | "TabIndicatorProps" | "TabScrollButtonProps" | "textColor" | "visibleScrollbar" | "slots" | "slotProps"> & {
1037
+ declare const PanelTabs: _emotion_styled.StyledComponent<_mui_material.TabsOwnProps & _mui_material_OverridableComponent.CommonProps & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "variant" | "children" | "className" | "value" | "style" | "aria-label" | "aria-labelledby" | "onChange" | "orientation" | "sx" | "classes" | "action" | "allowScrollButtonsMobile" | "centered" | "indicatorColor" | "ScrollButtonComponent" | "scrollButtons" | "selectionFollowsFocus" | "TabIndicatorProps" | "TabScrollButtonProps" | "textColor" | "visibleScrollbar" | "slots" | "slotProps"> & {
1013
1038
  theme?: _emotion_react.Theme;
1014
1039
  }, {}, {}>;
1015
- declare const PanelContent: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1040
+ declare const PanelContent: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1016
1041
  theme?: _emotion_react.Theme;
1017
1042
  }, {}, {}>;
1018
1043
  declare const FixedSVGContainer: _emotion_styled.StyledComponent<{
1019
1044
  theme?: _emotion_react.Theme;
1020
1045
  as?: React.ElementType;
1021
- }, react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1046
+ }, React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1022
1047
  declare const ScrollableSVGWrapper: _emotion_styled.StyledComponent<{
1023
1048
  theme?: _emotion_react.Theme;
1024
1049
  as?: React.ElementType;
1025
- }, react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1050
+ }, React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1026
1051
 
1027
1052
  declare const baseOverlayStyles: {
1028
1053
  readonly tank: {
@@ -1075,8 +1100,8 @@ declare const baseOverlayStyles: {
1075
1100
  };
1076
1101
  };
1077
1102
  declare const overlayStyles: Record<OverlayTheme, typeof baseOverlayStyles[OverlayTheme]>;
1078
- declare const SVGLockedOverlay: ({ svgX, svgY, children, theme, style, className, onClick, containerSelector, }: SVGLockedOverlayProps) => react.JSX.Element;
1079
- declare const DashboardCard: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1103
+ declare const SVGLockedOverlay: ({ svgX, svgY, children, theme, style, className, onClick, containerSelector, }: SVGLockedOverlayProps) => React$1.JSX.Element;
1104
+ declare const DashboardCard: _emotion_styled.StyledComponent<_mui_system.BoxOwnProps<_mui_material.Theme> & Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof _mui_system.BoxOwnProps<_mui_material.Theme>> & {
1080
1105
  theme?: _emotion_react.Theme;
1081
1106
  } & {
1082
1107
  svgX: number;
@@ -1088,23 +1113,23 @@ declare const CardHeader: _emotion_styled.StyledComponent<{
1088
1113
  as?: React.ElementType;
1089
1114
  } & {
1090
1115
  color?: string;
1091
- }, react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1116
+ }, React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1092
1117
  declare const CardValue: _emotion_styled.StyledComponent<{
1093
1118
  theme?: _emotion_react.Theme;
1094
1119
  as?: React.ElementType;
1095
- }, react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1120
+ }, React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1096
1121
  declare const CardUnit: _emotion_styled.StyledComponent<{
1097
1122
  theme?: _emotion_react.Theme;
1098
1123
  as?: React.ElementType;
1099
- }, react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1124
+ }, React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
1100
1125
 
1101
- declare const TrendLine: ({ values, width, height, color, strokeWidth, backgroundColor, forced, }: TrendLineProps) => react.JSX.Element;
1102
- declare const CircularGauge: ({ value, max, unit, label, size, color, forced, realValue, }: CircularGaugeProps) => react.JSX.Element;
1103
- declare const Sparkline: ({ data, width, height, color, forced }: SparklineProps) => react.JSX.Element | null;
1104
- declare const EquipmentIndicatorWithSparkline: ({ svgX, svgY, color, label, size, sparklineData, sparklineOffset, forced, }: EquipmentIndicatorWithSparklineProps) => react.JSX.Element;
1105
- declare const EquipmentIndicator: ({ svgX, svgY, color, label, size, style, className, forced, }: EquipmentIndicatorProps) => react.JSX.Element;
1126
+ declare const TrendLine: ({ values, width, height, color, strokeWidth, backgroundColor, forced, }: TrendLineProps) => React$1.JSX.Element;
1127
+ declare const CircularGauge: ({ value, max, unit, label, size, color, forced, realValue, }: CircularGaugeProps) => React$1.JSX.Element;
1128
+ declare const Sparkline: ({ data, width, height, color, forced }: SparklineProps) => React$1.JSX.Element | null;
1129
+ declare const EquipmentIndicatorWithSparkline: ({ svgX, svgY, color, label, size, sparklineData, sparklineOffset, forced, }: EquipmentIndicatorWithSparklineProps) => React$1.JSX.Element;
1130
+ declare const EquipmentIndicator: ({ svgX, svgY, color, label, size, style, className, forced, }: EquipmentIndicatorProps) => React$1.JSX.Element;
1106
1131
 
1107
- declare function FullscreenWorkspace({ svgContent, overlays, leftPanel, rightPanel, footer, tabs, activeTab, onTabChange, defaultLeftCollapsed, defaultRightCollapsed, leftCollapsed: leftCollapsedProp, rightCollapsed: rightCollapsedProp, onLeftCollapseChange, onRightCollapseChange, displayMode, defaultDisplayMode, onDisplayModeChange, showDisplayModeToggle, showZoomControls, onZoomIn, onZoomOut, onResetZoom, zoomDisabled, className, ...rest }: FullscreenWorkspaceProps): react__default.ReactElement;
1132
+ declare function FullscreenWorkspace({ svgContent, overlays, leftPanel, rightPanel, footer, tabs, activeTab, onTabChange, defaultLeftCollapsed, defaultRightCollapsed, leftCollapsed: leftCollapsedProp, rightCollapsed: rightCollapsedProp, onLeftCollapseChange, onRightCollapseChange, displayMode, defaultDisplayMode, onDisplayModeChange, showDisplayModeToggle, showZoomControls, onZoomIn, onZoomOut, onResetZoom, zoomDisabled, className, ...rest }: FullscreenWorkspaceProps): React__default.ReactElement;
1108
1133
 
1109
1134
  type Theme = 'modern' | 'hmi';
1110
1135
  interface ThemeContextType {
@@ -1114,17 +1139,17 @@ interface ThemeContextType {
1114
1139
  }
1115
1140
  declare const useTheme: () => ThemeContextType;
1116
1141
  interface ThemeProviderProps {
1117
- children: react__default.ReactNode;
1142
+ children: React__default.ReactNode;
1118
1143
  }
1119
- declare const ThemeProvider: react__default.FC<ThemeProviderProps>;
1144
+ declare const ThemeProvider: React__default.FC<ThemeProviderProps>;
1120
1145
 
1121
- interface ThemeToggleProps extends react__default.HTMLAttributes<HTMLDivElement> {
1146
+ interface ThemeToggleProps extends React__default.HTMLAttributes<HTMLDivElement> {
1122
1147
  /** Size of the toggle */
1123
1148
  size?: 'small' | 'medium' | 'large';
1124
1149
  /** Position of the toggle */
1125
1150
  position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'inline';
1126
1151
  }
1127
- declare const ThemeToggle: react__default.FC<ThemeToggleProps>;
1152
+ declare const ThemeToggle: React__default.FC<ThemeToggleProps>;
1128
1153
 
1129
1154
  /**
1130
1155
  * ISA-101 High Performance HMI — Unified Status Color System
@@ -1133,8 +1158,15 @@ declare const ThemeToggle: react__default.FC<ThemeToggleProps>;
1133
1158
  * Used by NodeRenderer (SVG fill/stroke), DeviceControlPanel (status indicator),
1134
1159
  * and DataOverlay (telemetry badge).
1135
1160
  */
1136
- /** Canonical device status vocabulary */
1137
- type DeviceStatus = 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping';
1161
+ /**
1162
+ * Canonical device status vocabulary.
1163
+ *
1164
+ * `unknown` marks a value the backend does not trust. OPC UA publishes this
1165
+ * condition as StatusCode severity Bad. The library never derives `unknown`
1166
+ * from a number or a threshold. The library only displays an `unknown` value
1167
+ * that the backend has already published.
1168
+ */
1169
+ type DeviceStatus = 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping' | 'unknown';
1138
1170
  /** Color entry covering both SVG node and overlay/panel needs */
1139
1171
  interface StatusColorEntry {
1140
1172
  /** Fill color for SVG node symbols */
@@ -1150,6 +1182,43 @@ interface StatusColorEntry {
1150
1182
  }
1151
1183
  /** Partial map for consumer overrides — only specify statuses you want to change */
1152
1184
  type StatusColorMap = Partial<Record<DeviceStatus, Partial<StatusColorEntry>>>;
1185
+ /**
1186
+ * The ISA unknown token, shared with the consuming application.
1187
+ *
1188
+ * The same token already marks an untrusted value on the consumer's Sidebar
1189
+ * and Interlocks screens. The library reuses it so one meaning has one
1190
+ * appearance across both products. See views-library issue #27.
1191
+ *
1192
+ * The library uses this one token for both unknown triggers: a node with
1193
+ * `status: 'unknown'` (an untrusted device) and a node with
1194
+ * `positionUnknown: true` (a disclaimed position). Both mean that the system
1195
+ * cannot confirm the state, so both get the same appearance.
1196
+ *
1197
+ * The hatch carries the meaning, not the fill. The flat `bg` sits a CIEDE2000
1198
+ * delta-E of 0.45 from the `off` fill after greyscale conversion, so the fill
1199
+ * alone cannot separate an untrusted device from a confirmed-off one. Any
1200
+ * surface that uses this token must also carry the hatch or a glyph.
1201
+ *
1202
+ * The hue is deliberate. Periwinkle at hue 240 sits between override violet
1203
+ * and interaction blue, so an operator cannot confuse the three.
1204
+ */
1205
+ declare const ISA_UNKNOWN: {
1206
+ readonly fg: "#4f4f8a";
1207
+ readonly bg: "#ebebf5";
1208
+ readonly border: "#8f8fc2";
1209
+ };
1210
+ /**
1211
+ * The dark-theme counterpart of `ISA_UNKNOWN`.
1212
+ *
1213
+ * `DEFAULT_STATUS_COLORS` carries the light values. Wiring a theme switch is
1214
+ * not part of this change; the constant exists so a consumer and a later
1215
+ * change can use the agreed values rather than inventing new ones.
1216
+ */
1217
+ declare const ISA_UNKNOWN_DARK: {
1218
+ readonly fg: "#b9bbdb";
1219
+ readonly bg: "#23263a";
1220
+ readonly border: "#6f74a3";
1221
+ };
1153
1222
  /**
1154
1223
  * ISA-101 defaults.
1155
1224
  *
@@ -1160,6 +1229,20 @@ type StatusColorMap = Partial<Record<DeviceStatus, Partial<StatusColorEntry>>>;
1160
1229
  * - off: light grey (matches canvas default #edeeef)
1161
1230
  * - starting: light green (transitional)
1162
1231
  * - stopping: amber (transitional)
1232
+ * - unknown: periwinkle (untrusted read; OPC UA severity Bad). Derived
1233
+ * from ISA_UNKNOWN above, the shared token.
1234
+ *
1235
+ * The unknown entry deliberately does NOT rely on its fill. The flat fill
1236
+ * sits a CIEDE2000 delta-E of 0.45 from the off fill after greyscale
1237
+ * conversion, so the two are indistinguishable without colour.
1238
+ *
1239
+ * Every unknown surface therefore carries a second channel that does not
1240
+ * depend on colour. Fixed-layout surfaces add a glyph. The P&ID symbol adds
1241
+ * a hatch. A surface that shows this fill alone reproduces the defect the
1242
+ * unknown status exists to close.
1243
+ *
1244
+ * This palette is not fully greyscale-separable: normal and alarm sit 1.6
1245
+ * apart. That is why unknown never relies on colour anywhere.
1163
1246
  */
1164
1247
  declare const DEFAULT_STATUS_COLORS: Record<DeviceStatus, StatusColorEntry>;
1165
1248
  /**
@@ -1173,6 +1256,16 @@ declare const DEFAULT_STATUS_COLORS: Record<DeviceStatus, StatusColorEntry>;
1173
1256
  * outlines a forced value's box/ring so it stays findable at a glance.
1174
1257
  */
1175
1258
  declare const FORCED_MARK_COLOR: StatusColorEntry;
1259
+ /**
1260
+ * Normalize a status string to its canonical `DeviceStatus` key.
1261
+ *
1262
+ * The function lowercases the value and follows `STATUS_ALIASES`. Every
1263
+ * caller that must decide "is this status X?" uses this function. A caller
1264
+ * that compares a raw string instead can disagree with `resolveStatusColor`
1265
+ * once an alias changes, which would let one surface paint a status the
1266
+ * other surface does not recognise.
1267
+ */
1268
+ declare function normalizeDeviceStatus(status: string | undefined): DeviceStatus;
1176
1269
  /**
1177
1270
  * Resolve a status string to a full color entry.
1178
1271
  *
@@ -1181,6 +1274,69 @@ declare const FORCED_MARK_COLOR: StatusColorEntry;
1181
1274
  */
1182
1275
  declare function resolveStatusColor(status: string | undefined, customMap?: StatusColorMap): StatusColorEntry;
1183
1276
 
1277
+ /**
1278
+ * Shared glyph for the `unknown` device status (KTD10).
1279
+ *
1280
+ * `StatusIndicator`, `DataOverlay`, and `DeviceControlPanel` import this one
1281
+ * module. One drawing keeps the marker consistent. An operator learns the
1282
+ * marker once and recognises it on every surface.
1283
+ *
1284
+ * The glyph is a question mark inside a dashed ring. The dashed ring is a
1285
+ * second channel that does not depend on colour. A broken outline reads as
1286
+ * an incomplete circuit.
1287
+ */
1288
+ /** Size keys the glyph accepts. These match `StatusIndicator`'s `size` prop. */
1289
+ type UnknownGlyphSize = 'small' | 'medium' | 'large';
1290
+ /**
1291
+ * CSS custom property that colours the glyph.
1292
+ *
1293
+ * A consumer sets this property on any ancestor to retheme the glyph.
1294
+ * `StatusIndicator` scopes it under the `ui-status-indicator--unknown` class.
1295
+ * The overlay and the control panel carry no such class, so a consumer sets
1296
+ * the property directly on those hosts. The glyph falls back to
1297
+ * `currentColor` when the consumer sets nothing, so the package never has to
1298
+ * ship CSS for it.
1299
+ */
1300
+ declare const UNKNOWN_STATUS_GLYPH_COLOR_VAR = "--ui-status-indicator-unknown-glyph-color";
1301
+ /**
1302
+ * Dash rhythm of the glyph's ring.
1303
+ *
1304
+ * The P&ID node symbol reuses this value for its own dashed outline. The
1305
+ * canvas cannot host a centred glyph, so it carries the same rhythm on the
1306
+ * symbol outline instead. Sharing the value keeps the two treatments in step.
1307
+ */
1308
+ declare const UNKNOWN_GLYPH_RING_DASH: string;
1309
+ interface UnknownStatusGlyphProps extends Omit<React__default.SVGProps<SVGSVGElement>, 'children' | 'viewBox'> {
1310
+ /** Size of the glyph. Sets the stroke weight (see `UNKNOWN_GLYPH_STROKE_WEIGHTS`). */
1311
+ size?: UnknownGlyphSize;
1312
+ /**
1313
+ * Counter-rotate the glyph.
1314
+ *
1315
+ * Set this to `true` when the host element applies `transform: rotate(45deg)`,
1316
+ * such as the `diamond` shape in `StatusIndicator`. The glyph then reads
1317
+ * upright instead of inheriting the host rotation.
1318
+ *
1319
+ * The counter-rotation is a fixed -45 degrees. It assumes the 45-degree
1320
+ * rotation that the documented `ui-status-indicator--diamond` rule applies.
1321
+ * A consumer that rotates the host by another angle must not set this flag.
1322
+ */
1323
+ counterRotate?: boolean;
1324
+ }
1325
+ /**
1326
+ * Renders the `unknown` status glyph as an inline `svg`.
1327
+ *
1328
+ * The glyph carries no CSS class dependency. It needs no stylesheet, so it
1329
+ * survives server-side rendering and needs no CSP nonce (KTD1).
1330
+ *
1331
+ * The `svg` is `aria-hidden` and `focusable="false"`. A separate unit adds
1332
+ * the accessible description.
1333
+ *
1334
+ * Remaining `svg` props pass straight through. An HTML host sizes the glyph
1335
+ * with `style`; an SVG host places it with `x`, `y`, `width`, and `height`,
1336
+ * because a nested `svg` accepts those as user-unit attributes.
1337
+ */
1338
+ declare function UnknownStatusGlyph({ size, counterRotate, style, ...rest }: UnknownStatusGlyphProps): React__default.ReactElement;
1339
+
1184
1340
  interface NodeInstance {
1185
1341
  id: string;
1186
1342
  symbolId: string;
@@ -1193,11 +1349,18 @@ interface NodeInstance {
1193
1349
  y: number;
1194
1350
  };
1195
1351
  labelFontSize?: number;
1196
- status?: 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping' | string;
1352
+ status?: 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping' | 'unknown' | string;
1197
1353
  customColors?: {
1198
1354
  fill?: string;
1199
1355
  stroke?: string;
1200
1356
  };
1357
+ /**
1358
+ * Opt-in. True when the control system has disclaimed this device's position
1359
+ * (for example a valve with bad limit-switch feedback). The symbol renders
1360
+ * with a diagonal hatch, a non-colour cue, so it differs from a CLOSED
1361
+ * symbol. Default off. Wins over status and customColors.
1362
+ */
1363
+ positionUnknown?: boolean;
1201
1364
  metadata?: Record<string, unknown>;
1202
1365
  }
1203
1366
  interface Transform {
@@ -1466,8 +1629,15 @@ declare function useTelemetry(options?: UseTelemetryOptions): UseTelemetryResult
1466
1629
  interface UseTelemetryStatusOptions {
1467
1630
  /** Whether status sync is enabled (default: true) */
1468
1631
  enabled?: boolean;
1469
- /** Custom status mapping function */
1470
- mapStatus?: (telemetryStatus: string) => string;
1632
+ /**
1633
+ * Custom status mapping function.
1634
+ *
1635
+ * A custom mapper replaces the default entirely. It must handle every
1636
+ * member of `TelemetryStatus`, including `unknown`. A mapper that returns
1637
+ * a healthy-looking status for `unknown` reintroduces the defect the
1638
+ * default mapping closes.
1639
+ */
1640
+ mapStatus?: (telemetryStatus: TelemetryStatus$1) => string;
1471
1641
  }
1472
1642
  /**
1473
1643
  * Hook to sync telemetry status to node instance status for dynamic coloring
@@ -1477,6 +1647,7 @@ interface UseTelemetryStatusOptions {
1477
1647
  * - 'warning' → 'warning'
1478
1648
  * - 'alarm' / 'fault' → 'alarm'
1479
1649
  * - 'off' → 'stopped'
1650
+ * - 'unknown' → 'unknown' (untrusted read; must not read as stopped)
1480
1651
  *
1481
1652
  * @param telemetry - Telemetry map from useTelemetry
1482
1653
  * @param diagram - Current diagram state
@@ -1495,6 +1666,34 @@ interface UseTelemetryStatusOptions {
1495
1666
  */
1496
1667
  declare function useTelemetryStatus(telemetry: TelemetryMap, diagram: Diagram, setDiagram: (diagram: Diagram) => void, options?: UseTelemetryStatusOptions): void;
1497
1668
 
1669
+ /** Options for the signal-binding sync. */
1670
+ interface UseBooleanIndicatorsOptions {
1671
+ /** Whether the sync is enabled (default: true). Disable in edit mode. */
1672
+ enabled?: boolean;
1673
+ /** Symbol id treated as a status indicator (default: 'status-indicator'). */
1674
+ symbolId?: string;
1675
+ }
1676
+ /**
1677
+ * Drive a status-indicator node's color and visibility from independent named
1678
+ * signals.
1679
+ *
1680
+ * Each indicator node names two tags in its metadata:
1681
+ * - `colorSource` — a tag whose truthy value shows `onColor`, falsy shows `offColor`.
1682
+ * - `visibleSource` — a tag whose truthy value shows the node, falsy hides it.
1683
+ *
1684
+ * Both are resolved against a tag → value index built from every published
1685
+ * telemetry binding, so color and visibility can follow completely different
1686
+ * signals. A blank source leaves that property alone (color unbound, visibility
1687
+ * static). Writes `customColors.fill` and `visible` — never touches the renderer
1688
+ * props, so the NodeRenderer memo boundary stays intact.
1689
+ *
1690
+ * @example
1691
+ * ```tsx
1692
+ * useBooleanIndicators(telemetry, diagram, setDiagram, { enabled: mode === 'runtime' });
1693
+ * ```
1694
+ */
1695
+ declare function useBooleanIndicators(telemetry: TelemetryMap, diagram: Diagram, setDiagram: (diagram: Diagram) => void, options?: UseBooleanIndicatorsOptions): void;
1696
+
1498
1697
  interface DragPoint {
1499
1698
  x: number;
1500
1699
  y: number;
@@ -1604,13 +1803,13 @@ interface PIDCanvasFeatures {
1604
1803
  /** Background color for canvas (default: '#ffffff') */
1605
1804
  backgroundColor?: string;
1606
1805
  }
1607
- interface PIDCanvasProps extends react__default.HTMLAttributes<HTMLDivElement> {
1806
+ interface PIDCanvasProps extends React__default.HTMLAttributes<HTMLDivElement> {
1608
1807
  /** The diagram to render */
1609
1808
  diagram: Diagram;
1610
1809
  /** Optional className for the container */
1611
1810
  className?: string;
1612
1811
  /** Optional inline styles for the container */
1613
- style?: react__default.CSSProperties;
1812
+ style?: React__default.CSSProperties;
1614
1813
  /** Enable interactive features (pan, zoom, selection, telemetry, dragNodes) */
1615
1814
  features?: PIDCanvasFeatures;
1616
1815
  /** Callback when selection changes */
@@ -1666,20 +1865,20 @@ interface PIDCanvasControls {
1666
1865
  *
1667
1866
  * Future: Editing tools, symbol library UI
1668
1867
  */
1669
- declare function PIDCanvasImpl({ diagram, className, style, features, onSelectionChange, onNodeClick, onPipeClick, onNodeMove, onDiagramChange, onDelete, onItemsCopied, onPaste, onSymbolDrop, onPipeCreated, onMounted, telemetry, statusColorMap, ...props }: PIDCanvasProps): react__default.ReactElement;
1868
+ declare function PIDCanvasImpl({ diagram, className, style, features, onSelectionChange, onNodeClick, onPipeClick, onNodeMove, onDiagramChange, onDelete, onItemsCopied, onPaste, onSymbolDrop, onPipeCreated, onMounted, telemetry, statusColorMap, ...props }: PIDCanvasProps): React__default.ReactElement;
1670
1869
  /**
1671
1870
  * Memo boundary - see PIDCanvasImpl doc comment (renderer-OOM fix). Shallow
1672
1871
  * compare: `diagram`, `telemetry`, `features`, `style`, `statusColorMap`, and
1673
1872
  * every callback are compared by identity; hosts that keep them stable skip
1674
1873
  * the full-canvas re-render entirely when unrelated screen state changes.
1675
1874
  */
1676
- declare const PIDCanvas: react__default.MemoExoticComponent<typeof PIDCanvasImpl>;
1875
+ declare const PIDCanvas: React__default.MemoExoticComponent<typeof PIDCanvasImpl>;
1677
1876
 
1678
1877
  interface SymbolLibraryProps {
1679
1878
  /** Optional className for styling */
1680
1879
  className?: string;
1681
1880
  /** Callback when a symbol drag starts */
1682
- onSymbolDragStart?: (symbolId: string, event: react__default.DragEvent) => void;
1881
+ onSymbolDragStart?: (symbolId: string, event: React__default.DragEvent) => void;
1683
1882
  /** Show category filter */
1684
1883
  showCategories?: boolean;
1685
1884
  /** Custom symbol categories */
@@ -1691,7 +1890,7 @@ interface SymbolLibraryProps {
1691
1890
  * Displays available symbols organized by category
1692
1891
  * Supports drag-and-drop to add new nodes to diagrams
1693
1892
  */
1694
- declare function SymbolLibrary({ className, onSymbolDragStart, showCategories, categories, }: SymbolLibraryProps): react__default.ReactElement;
1893
+ declare function SymbolLibrary({ className, onSymbolDragStart, showCategories, categories, }: SymbolLibraryProps): React__default.ReactElement;
1695
1894
 
1696
1895
  interface NodeConfigPanelProps {
1697
1896
  /** Selected node to configure */
@@ -1704,12 +1903,16 @@ interface NodeConfigPanelProps {
1704
1903
  onUpdateTelemetry: (updates: any) => void;
1705
1904
  /** Callback when telemetry binding is added for the first time */
1706
1905
  onAddTelemetry?: () => void;
1906
+ /** Callback to remove/clear the telemetry binding for this node */
1907
+ onRemoveTelemetry?: () => void;
1908
+ /** Known signal/tag names, used to autocomplete and validate 'tag' fields. */
1909
+ availableTags?: string[];
1707
1910
  /** Callback when node is removed */
1708
1911
  onRemove: () => void;
1709
1912
  /** Additional CSS class name */
1710
1913
  className?: string;
1711
1914
  /** Custom styles */
1712
- style?: react__default.CSSProperties;
1915
+ style?: React__default.CSSProperties;
1713
1916
  }
1714
1917
  /**
1715
1918
  * NodeConfigPanel - Reusable configuration panel for editing node properties and telemetry
@@ -1725,7 +1928,7 @@ interface NodeConfigPanelProps {
1725
1928
  * />
1726
1929
  * ```
1727
1930
  */
1728
- declare function NodeConfigPanel({ node, binding, onUpdateNode, onUpdateTelemetry, onAddTelemetry, onRemove, className, style, }: NodeConfigPanelProps): react__default.JSX.Element;
1931
+ declare function NodeConfigPanel({ node, binding, onUpdateNode, onUpdateTelemetry, onAddTelemetry, onRemoveTelemetry, availableTags, onRemove, className, style, }: NodeConfigPanelProps): React__default.JSX.Element;
1729
1932
 
1730
1933
  /**
1731
1934
  * Validates a diagram object structure
@@ -1806,6 +2009,60 @@ declare function getSymbolDefinition(symbolId: string): SymbolDefinition | undef
1806
2009
  */
1807
2010
  declare function getAvailableSymbols(): string[];
1808
2011
 
2012
+ /**
2013
+ * Appearance schema — the reusable contract for per-element editable properties.
2014
+ *
2015
+ * A placeable element declares its editable appearance fields as data. The
2016
+ * properties panel (NodeConfigPanel) renders any schema generically, and the
2017
+ * renderer (NodeRenderer) reads the same defaults. Add a new element by adding
2018
+ * one schema entry — no panel code changes. This is the pattern the
2019
+ * "add a placeable element" skill generates.
2020
+ */
2021
+ type AppearanceFieldKind = 'select' | 'boolean' | 'number' | 'text' | 'tag';
2022
+ /**
2023
+ * Where a field's value is read from and written to on the NodeInstance.
2024
+ * - 'metadata' (default): the untyped node.metadata bag, keyed by field.key
2025
+ * - 'visible': the node.visible flag
2026
+ * - 'scale': node.transform.scale (via valueMap for select options)
2027
+ */
2028
+ type AppearanceTarget = 'metadata' | 'visible' | 'scale';
2029
+ interface AppearanceField {
2030
+ /** metadata key, or the driver for the special 'visible'/'scale' targets */
2031
+ key: string;
2032
+ kind: AppearanceFieldKind;
2033
+ /** Human label for the panel; defaults to key when absent */
2034
+ label?: string;
2035
+ /** Options for kind 'select' */
2036
+ options?: string[];
2037
+ /** Where the value is stored; defaults to 'metadata' */
2038
+ target?: AppearanceTarget;
2039
+ /** Default value when the node has no value set */
2040
+ default?: string | number | boolean;
2041
+ /** For target 'scale': maps a select option to a numeric scale factor */
2042
+ valueMap?: Record<string, number>;
2043
+ /** Optional help text shown under the control in the panel */
2044
+ help?: string;
2045
+ }
2046
+ type AppearanceValue = string | number | boolean;
2047
+ /** Named color presets for the boolean indicator (name → hex). */
2048
+ declare const COLOR_PRESETS: Record<string, string>;
2049
+ /** Resolve a color preset name to a hex value, falling back to grey. */
2050
+ declare function resolvePresetColor(name: string | undefined): string;
2051
+ /** Appearance schema for the Status LED symbol. */
2052
+ declare const STATUS_LED_APPEARANCE: AppearanceField[];
2053
+ /** Return the editable appearance fields for a symbol, or [] if it declares none. */
2054
+ declare function getAppearanceSchema(symbolId: string): AppearanceField[];
2055
+ /**
2056
+ * Default values for the 'metadata'-targeted fields of a symbol, keyed by field key.
2057
+ * The renderer merges these under the node's own metadata, so a freshly dropped
2058
+ * element looks correct before any editing.
2059
+ */
2060
+ declare function getAppearanceDefaults(symbolId: string): Record<string, AppearanceValue>;
2061
+ /** Read the current value of a field from a node, applying the field default. */
2062
+ declare function readAppearanceValue(node: NodeInstance, field: AppearanceField): AppearanceValue;
2063
+ /** Produce the NodeInstance update for a new field value. */
2064
+ declare function writeAppearanceValue(node: NodeInstance, field: AppearanceField, value: AppearanceValue): Partial<NodeInstance>;
2065
+
1809
2066
  /**
1810
2067
  * Telemetry status type
1811
2068
  */
@@ -2180,9 +2437,9 @@ interface DeviceConfigPanelProps {
2180
2437
  * pays off when the host passes identity-stable `binding` and handler props;
2181
2438
  * an unstable host degrades gracefully to the old behavior.
2182
2439
  */
2183
- declare function DeviceConfigPanelImpl({ binding, onClose, onUndock, undockIcon, position, align, touchOptimized, compact, fontScale, maxHeight, maxWidth, toastDuration, onOpenControls, showControlsButton, showBuiltInToast, embedded, }: DeviceConfigPanelProps): react__default.JSX.Element | null;
2440
+ declare function DeviceConfigPanelImpl({ binding, onClose, onUndock, undockIcon, position, align, touchOptimized, compact, fontScale, maxHeight, maxWidth, toastDuration, onOpenControls, showControlsButton, showBuiltInToast, embedded, }: DeviceConfigPanelProps): React__default.JSX.Element | null;
2184
2441
  /** Memo boundary - see DeviceConfigPanelImpl doc comment (kiosk heap-leak fix). */
2185
- declare const DeviceConfigPanel: react__default.MemoExoticComponent<typeof DeviceConfigPanelImpl>;
2442
+ declare const DeviceConfigPanel: React__default.MemoExoticComponent<typeof DeviceConfigPanelImpl>;
2186
2443
 
2187
2444
  /**
2188
2445
  * Options for simulation behavior
@@ -2222,4 +2479,4 @@ interface SimulationOptions {
2222
2479
  */
2223
2480
  declare function useSimulation(telemetry: TelemetryMap, updateTelemetryBatch: (updates: Array<any>) => void, options?: SimulationOptions): void;
2224
2481
 
2225
- export { type AnchorType, Button, type ButtonProps, CardHeader, CardUnit, CardValue, CircularGauge, type CircularGaugeProps, type CommandKind, type ConfigActions, type ConfigDisplay, type ConfigParameter, type ConfigSection, type ConfigState, type ConfigTheme, type ControlCapabilities, type ControlMode, ControlPanel, type ControlPanelProps, type ControlParameter, type ControlState, type CustomAction, DEFAULT_STATUS_COLORS, DEFAULT_THRESHOLDS, DashboardCard, type DataBinding, type DeviceConfigBinding, type DeviceConfigMap, DeviceConfigPanel, type DeviceConfigPanelProps, type DeviceControlBinding, type DeviceControlMap, DeviceControlPanel, type DeviceControlPanelProps, type DeviceStatus, type Diagram, type DiagramMetadata, type DisplayMode, DisplayModeToggle, type DragPoint, type DragState, EquipmentIndicator, type EquipmentIndicatorProps, EquipmentIndicatorWithSparkline, type EquipmentIndicatorWithSparklineProps, FORCED_MARK_COLOR, FixedSVGContainer, FooterPanel, type ForcedState, FullscreenContainer, FullscreenWorkspace, type FullscreenWorkspaceProps, type FullscreenWorkspaceTab, type KeyboardShortcutsOptions, LeftPanel, LeftToggleButton, LegacyValueEntry, type LegacyValueEntryProps, type ModeConfig, NodeConfigPanel, type NodeConfigPanelProps, type NodeControlConfig, NodeControlsPanel, type NodeControlsPanelProps, type NodeInstance, NumpadDialog, type NumpadDialogProps, type Overlay, type OverlayContent, type OverlayTheme, type OverlayType, PIDCanvas, type PIDCanvasControls, type PIDCanvasFeatures, type PIDCanvasProps, PanelContent, PanelTabs, type PipeEdge, type PipeStyle, type Point, type PortDefinition, type PortInstance, type PortType, RightPanel, RightToggleButton, SVGArea, SVGLockedOverlay, type SVGLockedOverlayProps, type ScalingMetadata, ScrollableSVGWrapper, type SelectionState, Selector, type SelectorOption, type SelectorProps, type SimulationOptions, Sparkline, type SparklineProps, type StatusColorEntry, type StatusColorMap, StatusIndicator, type StatusIndicatorProps, type SymbolCategory, type SymbolDefinition, SymbolLibrary, type SymbolLibraryProps, type SymbolMetadata, type TelemetryBinding, type TelemetryMap, type TelemetryStatus$1 as TelemetryStatus, type TelemetryValue, ThemeProvider, ThemeToggle, type ThemeToggleProps, type Thresholds, type Transform, TrendLine, type TrendLineProps, type UseDeviceControlsOptions, type UseDragOptions, type UseDragResult, type UseSelectionOptions, type UseSelectionResult, type UseTelemetryOptions, type UseTelemetryResult, type UseTelemetryStatusOptions, type UseViewBoxOptions, type UseViewBoxResult, ValueEntry, type ValueEntryProps, type ViewBox, ZoomButton, ZoomControls, calculateThresholdStatus, createConfigBinding, createControlBinding, exampleDiagram, exportDiagram, generateRoutePoints, getAvailableSymbols, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, overlayStyles, registerSymbol, registerSymbols, resolveStatusColor, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram };
2482
+ export { type AnchorType, type AppearanceField, type AppearanceFieldKind, type AppearanceTarget, type AppearanceValue, Button, type ButtonProps, COLOR_PRESETS, CardHeader, CardUnit, CardValue, CircularGauge, type CircularGaugeProps, type CommandKind, type ConfigActions, type ConfigDisplay, type ConfigParameter, type ConfigSection, type ConfigState, type ConfigTheme, type ControlCapabilities, type ControlMode, ControlPanel, type ControlPanelProps, type ControlParameter, type ControlState, type CustomAction, DEFAULT_STATUS_COLORS, DEFAULT_THRESHOLDS, DashboardCard, type DataBinding, type DeviceConfigBinding, type DeviceConfigMap, DeviceConfigPanel, type DeviceConfigPanelProps, type DeviceControlBinding, type DeviceControlMap, DeviceControlPanel, type DeviceControlPanelProps, type DeviceStatus, type Diagram, type DiagramMetadata, type DisplayMode, DisplayModeToggle, type DragPoint, type DragState, EquipmentIndicator, type EquipmentIndicatorProps, EquipmentIndicatorWithSparkline, type EquipmentIndicatorWithSparklineProps, FORCED_MARK_COLOR, FixedSVGContainer, FooterPanel, type ForcedState, FullscreenContainer, FullscreenWorkspace, type FullscreenWorkspaceProps, type FullscreenWorkspaceTab, ISA_UNKNOWN, ISA_UNKNOWN_DARK, type KeyboardShortcutsOptions, LeftPanel, LeftToggleButton, LegacyValueEntry, type LegacyValueEntryProps, type ModeConfig, NodeConfigPanel, type NodeConfigPanelProps, type NodeControlConfig, NodeControlsPanel, type NodeControlsPanelProps, type NodeInstance, NumpadDialog, type NumpadDialogProps, type Overlay, type OverlayContent, type OverlayTheme, type OverlayType, PIDCanvas, type PIDCanvasControls, type PIDCanvasFeatures, type PIDCanvasProps, PanelContent, PanelTabs, type PipeEdge, type PipeStyle, type Point, type PortDefinition, type PortInstance, type PortType, RightPanel, RightToggleButton, STATUS_LED_APPEARANCE, SVGArea, SVGLockedOverlay, type SVGLockedOverlayProps, type ScalingMetadata, ScrollableSVGWrapper, type SelectionState, Selector, type SelectorOption, type SelectorProps, type SimulationOptions, Sparkline, type SparklineProps, type StatusColorEntry, type StatusColorMap, StatusIndicator, type StatusIndicatorProps, type SymbolCategory, type SymbolDefinition, SymbolLibrary, type SymbolLibraryProps, type SymbolMetadata, type TelemetryBinding, type TelemetryMap, type TelemetryStatus$1 as TelemetryStatus, type TelemetryValue, ThemeProvider, ThemeToggle, type ThemeToggleProps, type Thresholds, type Transform, TrendLine, type TrendLineProps, UNKNOWN_GLYPH_RING_DASH, UNKNOWN_STATUS_GLYPH_COLOR_VAR, type UnknownGlyphSize, UnknownStatusGlyph, type UnknownStatusGlyphProps, type UseBooleanIndicatorsOptions, type UseDeviceControlsOptions, type UseDragOptions, type UseDragResult, type UseSelectionOptions, type UseSelectionResult, type UseTelemetryOptions, type UseTelemetryResult, type UseTelemetryStatusOptions, type UseViewBoxOptions, type UseViewBoxResult, ValueEntry, type ValueEntryProps, type ViewBox, ZoomButton, ZoomControls, calculateThresholdStatus, createConfigBinding, createControlBinding, exampleDiagram, exportDiagram, generateRoutePoints, getAppearanceDefaults, getAppearanceSchema, getAvailableSymbols, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, normalizeDeviceStatus, overlayStyles, readAppearanceValue, registerSymbol, registerSymbols, resolvePresetColor, resolveStatusColor, useBooleanIndicators, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram, writeAppearanceValue };