@procaaso/alphinity-ui-components 1.12.0 → 1.13.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
@@ -1337,6 +1337,54 @@ interface UnknownStatusGlyphProps extends Omit<React__default.SVGProps<SVGSVGEle
1337
1337
  */
1338
1338
  declare function UnknownStatusGlyph({ size, counterRotate, style, ...rest }: UnknownStatusGlyphProps): React__default.ReactElement;
1339
1339
 
1340
+ /**
1341
+ * A corner badge slot on a node (#33).
1342
+ *
1343
+ * A badge marks a condition that is NOT a health severity (`NodeInstance.status`)
1344
+ * and must never replace the node's body color. A device can be tripped AND
1345
+ * blocked at the same time; `status` shows the trip, the badge shows the
1346
+ * block, and both render at once. This is a general slot, not a fixed
1347
+ * prohibition badge: the consumer names the glyph, the colors, the corner,
1348
+ * the size, and the motion. Register additional glyphs with
1349
+ * `registerBadgeGlyph` (`src/diagram/badges`) rather than hardcoding a new
1350
+ * one here.
1351
+ */
1352
+ interface NodeBadgeAppearance {
1353
+ /**
1354
+ * Which glyph to draw. `'prohibit'` (a circle with a slash) ships with the
1355
+ * library. The set is extensible: register more with `registerBadgeGlyph`
1356
+ * / `registerBadgeGlyphs` and reference them by id here, the same way
1357
+ * `symbolId` references a registered symbol.
1358
+ */
1359
+ glyph: 'prohibit' | string;
1360
+ /** Glyph color (stroke/fill). Consumer picks; no status-driven default. */
1361
+ color?: string;
1362
+ /** Disc background color behind the glyph. Consumer picks. */
1363
+ backgroundColor?: string;
1364
+ /** Which corner of the node's bounding box the badge anchors to. Defaults to 'top-right'. */
1365
+ corner?: NodeBadgeCorner;
1366
+ /** Badge disc diameter, in the symbol's local SVG units. Defaults to 14. */
1367
+ size?: number;
1368
+ /** Accessible label read by assistive tech (e.g. "Start blocked"). */
1369
+ label?: string;
1370
+ }
1371
+ type NodeBadgeCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
1372
+ /**
1373
+ * Motion for a `NodeBadge`. Steady by default. A consumer that turns on
1374
+ * `blink` MUST supply `blinkPeriodMs` - the library has no default period.
1375
+ * TFFi drives its status tower, its batch bar, and this badge off one shared
1376
+ * constant so all three beat together; a period fixed in the library would
1377
+ * break that agreement, so there is deliberately no fallback value here.
1378
+ */
1379
+ type NodeBadgeMotion = {
1380
+ blink?: false;
1381
+ } | {
1382
+ blink: true;
1383
+ blinkPeriodMs: number;
1384
+ };
1385
+ /** The full badge: appearance plus motion. This is the type `NodeInstance.badge` carries. */
1386
+ type NodeBadge = NodeBadgeAppearance & NodeBadgeMotion;
1387
+
1340
1388
  interface NodeInstance {
1341
1389
  id: string;
1342
1390
  symbolId: string;
@@ -1361,6 +1409,13 @@ interface NodeInstance {
1361
1409
  * symbol. Default off. Wins over status and customColors.
1362
1410
  */
1363
1411
  positionUnknown?: boolean;
1412
+ /**
1413
+ * A corner badge for a condition that is NOT a health severity (#33),
1414
+ * e.g. a device blocked from starting. Stacks on top of `status` /
1415
+ * `customColors` / `positionUnknown` - it never replaces the node's body
1416
+ * color, so a node can show `status: 'fault'` and a badge at once.
1417
+ */
1418
+ badge?: NodeBadge;
1364
1419
  metadata?: Record<string, unknown>;
1365
1420
  }
1366
1421
  interface Transform {
@@ -2063,6 +2118,36 @@ declare function readAppearanceValue(node: NodeInstance, field: AppearanceField)
2063
2118
  /** Produce the NodeInstance update for a new field value. */
2064
2119
  declare function writeAppearanceValue(node: NodeInstance, field: AppearanceField, value: AppearanceValue): Partial<NodeInstance>;
2065
2120
 
2121
+ /**
2122
+ * Registry of badge glyphs for the `NodeBadge` corner slot (#33).
2123
+ *
2124
+ * Mirrors `diagram/symbols/mockSymbolLibrary`'s registration pattern: a
2125
+ * built-in set plus a consumer-registered set, looked up by id. A consumer
2126
+ * calls `registerBadgeGlyph` from its own app code to add a glyph the
2127
+ * library does not ship - the same escape hatch `registerSymbol` already
2128
+ * gives P&ID symbols. This is deliberately NOT a string resolved only
2129
+ * inside the library (the mistake `Overlay.content.component` made, per
2130
+ * #33): the consumer supplies the real markup.
2131
+ */
2132
+ interface BadgeGlyphDefinition {
2133
+ /** Id a `NodeBadge.glyph` references. */
2134
+ id: string;
2135
+ /**
2136
+ * Raw SVG markup, drawn centered in a 24x24 local box (0,0 to 24,24).
2137
+ * Use `stroke="currentColor"` / `fill="currentColor"` so the glyph picks
2138
+ * up `NodeBadge.color` - the glyph carries no color of its own, only shape.
2139
+ */
2140
+ svgContent: string;
2141
+ }
2142
+ /** Register a single custom badge glyph, or replace a built-in one by reusing its id. */
2143
+ declare function registerBadgeGlyph(glyph: BadgeGlyphDefinition): void;
2144
+ /** Register multiple custom badge glyphs at once. */
2145
+ declare function registerBadgeGlyphs(glyphs: BadgeGlyphDefinition[] | Record<string, BadgeGlyphDefinition>): void;
2146
+ /** Get a badge glyph definition by id (checks custom glyphs before built-ins). */
2147
+ declare function getBadgeGlyph(glyphId: string): BadgeGlyphDefinition | undefined;
2148
+ /** List every registered badge glyph id (built-in plus custom). */
2149
+ declare function getAvailableBadgeGlyphs(): string[];
2150
+
2066
2151
  /**
2067
2152
  * Telemetry status type
2068
2153
  */
@@ -2479,4 +2564,4 @@ interface SimulationOptions {
2479
2564
  */
2480
2565
  declare function useSimulation(telemetry: TelemetryMap, updateTelemetryBatch: (updates: Array<any>) => void, options?: SimulationOptions): void;
2481
2566
 
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 };
2567
+ export { type AnchorType, type AppearanceField, type AppearanceFieldKind, type AppearanceTarget, type AppearanceValue, type BadgeGlyphDefinition, 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, type NodeBadge, type NodeBadgeAppearance, type NodeBadgeCorner, type NodeBadgeMotion, 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, getAvailableBadgeGlyphs, getAvailableSymbols, getBadgeGlyph, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, normalizeDeviceStatus, overlayStyles, readAppearanceValue, registerBadgeGlyph, registerBadgeGlyphs, registerSymbol, registerSymbols, resolvePresetColor, resolveStatusColor, useBooleanIndicators, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram, writeAppearanceValue };
package/dist/index.d.ts CHANGED
@@ -1337,6 +1337,54 @@ interface UnknownStatusGlyphProps extends Omit<React__default.SVGProps<SVGSVGEle
1337
1337
  */
1338
1338
  declare function UnknownStatusGlyph({ size, counterRotate, style, ...rest }: UnknownStatusGlyphProps): React__default.ReactElement;
1339
1339
 
1340
+ /**
1341
+ * A corner badge slot on a node (#33).
1342
+ *
1343
+ * A badge marks a condition that is NOT a health severity (`NodeInstance.status`)
1344
+ * and must never replace the node's body color. A device can be tripped AND
1345
+ * blocked at the same time; `status` shows the trip, the badge shows the
1346
+ * block, and both render at once. This is a general slot, not a fixed
1347
+ * prohibition badge: the consumer names the glyph, the colors, the corner,
1348
+ * the size, and the motion. Register additional glyphs with
1349
+ * `registerBadgeGlyph` (`src/diagram/badges`) rather than hardcoding a new
1350
+ * one here.
1351
+ */
1352
+ interface NodeBadgeAppearance {
1353
+ /**
1354
+ * Which glyph to draw. `'prohibit'` (a circle with a slash) ships with the
1355
+ * library. The set is extensible: register more with `registerBadgeGlyph`
1356
+ * / `registerBadgeGlyphs` and reference them by id here, the same way
1357
+ * `symbolId` references a registered symbol.
1358
+ */
1359
+ glyph: 'prohibit' | string;
1360
+ /** Glyph color (stroke/fill). Consumer picks; no status-driven default. */
1361
+ color?: string;
1362
+ /** Disc background color behind the glyph. Consumer picks. */
1363
+ backgroundColor?: string;
1364
+ /** Which corner of the node's bounding box the badge anchors to. Defaults to 'top-right'. */
1365
+ corner?: NodeBadgeCorner;
1366
+ /** Badge disc diameter, in the symbol's local SVG units. Defaults to 14. */
1367
+ size?: number;
1368
+ /** Accessible label read by assistive tech (e.g. "Start blocked"). */
1369
+ label?: string;
1370
+ }
1371
+ type NodeBadgeCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
1372
+ /**
1373
+ * Motion for a `NodeBadge`. Steady by default. A consumer that turns on
1374
+ * `blink` MUST supply `blinkPeriodMs` - the library has no default period.
1375
+ * TFFi drives its status tower, its batch bar, and this badge off one shared
1376
+ * constant so all three beat together; a period fixed in the library would
1377
+ * break that agreement, so there is deliberately no fallback value here.
1378
+ */
1379
+ type NodeBadgeMotion = {
1380
+ blink?: false;
1381
+ } | {
1382
+ blink: true;
1383
+ blinkPeriodMs: number;
1384
+ };
1385
+ /** The full badge: appearance plus motion. This is the type `NodeInstance.badge` carries. */
1386
+ type NodeBadge = NodeBadgeAppearance & NodeBadgeMotion;
1387
+
1340
1388
  interface NodeInstance {
1341
1389
  id: string;
1342
1390
  symbolId: string;
@@ -1361,6 +1409,13 @@ interface NodeInstance {
1361
1409
  * symbol. Default off. Wins over status and customColors.
1362
1410
  */
1363
1411
  positionUnknown?: boolean;
1412
+ /**
1413
+ * A corner badge for a condition that is NOT a health severity (#33),
1414
+ * e.g. a device blocked from starting. Stacks on top of `status` /
1415
+ * `customColors` / `positionUnknown` - it never replaces the node's body
1416
+ * color, so a node can show `status: 'fault'` and a badge at once.
1417
+ */
1418
+ badge?: NodeBadge;
1364
1419
  metadata?: Record<string, unknown>;
1365
1420
  }
1366
1421
  interface Transform {
@@ -2063,6 +2118,36 @@ declare function readAppearanceValue(node: NodeInstance, field: AppearanceField)
2063
2118
  /** Produce the NodeInstance update for a new field value. */
2064
2119
  declare function writeAppearanceValue(node: NodeInstance, field: AppearanceField, value: AppearanceValue): Partial<NodeInstance>;
2065
2120
 
2121
+ /**
2122
+ * Registry of badge glyphs for the `NodeBadge` corner slot (#33).
2123
+ *
2124
+ * Mirrors `diagram/symbols/mockSymbolLibrary`'s registration pattern: a
2125
+ * built-in set plus a consumer-registered set, looked up by id. A consumer
2126
+ * calls `registerBadgeGlyph` from its own app code to add a glyph the
2127
+ * library does not ship - the same escape hatch `registerSymbol` already
2128
+ * gives P&ID symbols. This is deliberately NOT a string resolved only
2129
+ * inside the library (the mistake `Overlay.content.component` made, per
2130
+ * #33): the consumer supplies the real markup.
2131
+ */
2132
+ interface BadgeGlyphDefinition {
2133
+ /** Id a `NodeBadge.glyph` references. */
2134
+ id: string;
2135
+ /**
2136
+ * Raw SVG markup, drawn centered in a 24x24 local box (0,0 to 24,24).
2137
+ * Use `stroke="currentColor"` / `fill="currentColor"` so the glyph picks
2138
+ * up `NodeBadge.color` - the glyph carries no color of its own, only shape.
2139
+ */
2140
+ svgContent: string;
2141
+ }
2142
+ /** Register a single custom badge glyph, or replace a built-in one by reusing its id. */
2143
+ declare function registerBadgeGlyph(glyph: BadgeGlyphDefinition): void;
2144
+ /** Register multiple custom badge glyphs at once. */
2145
+ declare function registerBadgeGlyphs(glyphs: BadgeGlyphDefinition[] | Record<string, BadgeGlyphDefinition>): void;
2146
+ /** Get a badge glyph definition by id (checks custom glyphs before built-ins). */
2147
+ declare function getBadgeGlyph(glyphId: string): BadgeGlyphDefinition | undefined;
2148
+ /** List every registered badge glyph id (built-in plus custom). */
2149
+ declare function getAvailableBadgeGlyphs(): string[];
2150
+
2066
2151
  /**
2067
2152
  * Telemetry status type
2068
2153
  */
@@ -2479,4 +2564,4 @@ interface SimulationOptions {
2479
2564
  */
2480
2565
  declare function useSimulation(telemetry: TelemetryMap, updateTelemetryBatch: (updates: Array<any>) => void, options?: SimulationOptions): void;
2481
2566
 
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 };
2567
+ export { type AnchorType, type AppearanceField, type AppearanceFieldKind, type AppearanceTarget, type AppearanceValue, type BadgeGlyphDefinition, 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, type NodeBadge, type NodeBadgeAppearance, type NodeBadgeCorner, type NodeBadgeMotion, 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, getAvailableBadgeGlyphs, getAvailableSymbols, getBadgeGlyph, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, normalizeDeviceStatus, overlayStyles, readAppearanceValue, registerBadgeGlyph, registerBadgeGlyphs, registerSymbol, registerSymbols, resolvePresetColor, resolveStatusColor, useBooleanIndicators, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram, writeAppearanceValue };
package/dist/index.js CHANGED
@@ -5031,6 +5031,32 @@ function writeAppearanceValue(node, field, value) {
5031
5031
  return { metadata: { ...node.metadata, [field.key]: value } };
5032
5032
  }
5033
5033
 
5034
+ // src/diagram/badges/nodeBadgeGlyphs.ts
5035
+ var PROHIBIT_GLYPH = {
5036
+ id: "prohibit",
5037
+ svgContent: '<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2.4"/><line x1="5.6" y1="18.4" x2="18.4" y2="5.6" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/>'
5038
+ };
5039
+ var builtInBadgeGlyphs = {
5040
+ [PROHIBIT_GLYPH.id]: PROHIBIT_GLYPH
5041
+ };
5042
+ var customBadgeGlyphs = {};
5043
+ function registerBadgeGlyph(glyph) {
5044
+ customBadgeGlyphs[glyph.id] = glyph;
5045
+ }
5046
+ function registerBadgeGlyphs(glyphs) {
5047
+ if (Array.isArray(glyphs)) {
5048
+ glyphs.forEach((glyph) => registerBadgeGlyph(glyph));
5049
+ } else {
5050
+ Object.values(glyphs).forEach((glyph) => registerBadgeGlyph(glyph));
5051
+ }
5052
+ }
5053
+ function getBadgeGlyph(glyphId) {
5054
+ return customBadgeGlyphs[glyphId] ?? builtInBadgeGlyphs[glyphId];
5055
+ }
5056
+ function getAvailableBadgeGlyphs() {
5057
+ return [...Object.keys(customBadgeGlyphs), ...Object.keys(builtInBadgeGlyphs)];
5058
+ }
5059
+
5034
5060
  // src/components/PIDCanvas/NodeRenderer.tsx
5035
5061
  import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
5036
5062
  var HATCH_TILE_SIZE = 7;
@@ -5040,6 +5066,75 @@ var HATCH_STRIPE_OPACITY = 85 / 255;
5040
5066
  function isUnknownNode(node) {
5041
5067
  return node.positionUnknown === true || normalizeDeviceStatus(node.status) === "unknown";
5042
5068
  }
5069
+ var DEFAULT_BADGE_CORNER = "top-right";
5070
+ var DEFAULT_BADGE_SIZE = 14;
5071
+ var DEFAULT_BADGE_COLOR = "#111827";
5072
+ var DEFAULT_BADGE_BACKGROUND = "#d1d5db";
5073
+ var BADGE_GLYPH_BOX = 24;
5074
+ var BADGE_BLINK_KEYFRAME_ID = "pid-node-badge-blink-keyframes";
5075
+ var BADGE_BLINK_KEYFRAME_NAME = "pid-node-badge-blink";
5076
+ function ensureBadgeBlinkKeyframes() {
5077
+ if (typeof document === "undefined") return;
5078
+ if (document.getElementById(BADGE_BLINK_KEYFRAME_ID)) return;
5079
+ const style = document.createElement("style");
5080
+ style.id = BADGE_BLINK_KEYFRAME_ID;
5081
+ style.textContent = `@keyframes ${BADGE_BLINK_KEYFRAME_NAME}{0%{opacity:1}50%{opacity:.15}100%{opacity:1}}`;
5082
+ document.head.appendChild(style);
5083
+ }
5084
+ function badgeCenter(corner, vb, size) {
5085
+ const margin = size / 4;
5086
+ switch (corner) {
5087
+ case "top-left":
5088
+ return { x: -margin, y: -margin };
5089
+ case "bottom-left":
5090
+ return { x: -margin, y: vb.height + margin };
5091
+ case "bottom-right":
5092
+ return { x: vb.width + margin, y: vb.height + margin };
5093
+ case "top-right":
5094
+ default:
5095
+ return { x: vb.width + margin, y: -margin };
5096
+ }
5097
+ }
5098
+ function renderNodeBadge(badge, vb, rotation) {
5099
+ const glyphDef = getBadgeGlyph(badge.glyph);
5100
+ const size = badge.size ?? DEFAULT_BADGE_SIZE;
5101
+ const color = badge.color ?? DEFAULT_BADGE_COLOR;
5102
+ const backgroundColor = badge.backgroundColor ?? DEFAULT_BADGE_BACKGROUND;
5103
+ const corner = badge.corner ?? DEFAULT_BADGE_CORNER;
5104
+ const { x: cx, y: cy } = badgeCenter(corner, vb, size);
5105
+ const radius = size / 2;
5106
+ const glyphScale = size / BADGE_GLYPH_BOX;
5107
+ let blinkStyle;
5108
+ if (badge.blink) {
5109
+ ensureBadgeBlinkKeyframes();
5110
+ blinkStyle = {
5111
+ animation: `${BADGE_BLINK_KEYFRAME_NAME} ${badge.blinkPeriodMs}ms ease-in-out infinite`
5112
+ };
5113
+ }
5114
+ return /* @__PURE__ */ jsxs13(
5115
+ "g",
5116
+ {
5117
+ "data-node-badge": badge.glyph,
5118
+ "data-badge-corner": corner,
5119
+ "data-badge-blink": badge.blink ? "true" : "false",
5120
+ "aria-label": badge.label,
5121
+ role: badge.label ? "img" : void 0,
5122
+ transform: rotation ? `translate(${cx}, ${cy}) rotate(${-rotation})` : `translate(${cx}, ${cy})`,
5123
+ style: blinkStyle,
5124
+ children: [
5125
+ /* @__PURE__ */ jsx17("circle", { r: radius, fill: backgroundColor }),
5126
+ glyphDef && /* @__PURE__ */ jsx17(
5127
+ "g",
5128
+ {
5129
+ color,
5130
+ transform: `scale(${glyphScale}) translate(${-BADGE_GLYPH_BOX / 2}, ${-BADGE_GLYPH_BOX / 2})`,
5131
+ dangerouslySetInnerHTML: { __html: glyphDef.svgContent }
5132
+ }
5133
+ )
5134
+ ]
5135
+ }
5136
+ );
5137
+ }
5043
5138
  function NodeRendererImpl({
5044
5139
  nodes: nodes2,
5045
5140
  selectedNodeIds,
@@ -5246,7 +5341,8 @@ function NodeRendererImpl({
5246
5341
  transform: node.transform.rotation ? `rotate(${-node.transform.rotation}, ${labelX}, ${labelY})` : void 0,
5247
5342
  children: node.label || node.id
5248
5343
  }
5249
- )
5344
+ ),
5345
+ node.badge && renderNodeBadge(node.badge, vb, node.transform.rotation)
5250
5346
  ]
5251
5347
  },
5252
5348
  node.id
@@ -10341,7 +10437,9 @@ export {
10341
10437
  generateRoutePoints,
10342
10438
  getAppearanceDefaults,
10343
10439
  getAppearanceSchema,
10440
+ getAvailableBadgeGlyphs,
10344
10441
  getAvailableSymbols,
10442
+ getBadgeGlyph,
10345
10443
  getPortWorldPosition,
10346
10444
  getSymbolDefinition,
10347
10445
  importDiagram,
@@ -10350,6 +10448,8 @@ export {
10350
10448
  normalizeDeviceStatus,
10351
10449
  overlayStyles,
10352
10450
  readAppearanceValue,
10451
+ registerBadgeGlyph,
10452
+ registerBadgeGlyphs,
10353
10453
  registerSymbol,
10354
10454
  registerSymbols,
10355
10455
  resolvePresetColor,