@adcops/autocore-react 3.0.40 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/additional-docs/AutoCoreTagContext.md +441 -0
  2. package/additional-docs/react_performance_notes.md +94 -0
  3. package/dist/assets/BlocklyLogo.d.ts +1 -0
  4. package/dist/assets/BlocklyLogo.d.ts.map +1 -0
  5. package/dist/assets/Distance.d.ts +1 -0
  6. package/dist/assets/Distance.d.ts.map +1 -0
  7. package/dist/assets/JogLong.d.ts +1 -0
  8. package/dist/assets/JogLong.d.ts.map +1 -0
  9. package/dist/assets/JogMedium.d.ts +1 -0
  10. package/dist/assets/JogMedium.d.ts.map +1 -0
  11. package/dist/assets/JogShort.d.ts +1 -0
  12. package/dist/assets/JogShort.d.ts.map +1 -0
  13. package/dist/assets/PythonLogo.d.ts +1 -0
  14. package/dist/assets/PythonLogo.d.ts.map +1 -0
  15. package/dist/assets/Rotation3D.d.ts +1 -0
  16. package/dist/assets/Rotation3D.d.ts.map +1 -0
  17. package/dist/assets/RotationCcw.d.ts +1 -0
  18. package/dist/assets/RotationCcw.d.ts.map +1 -0
  19. package/dist/assets/RotationCcwA.d.ts +1 -0
  20. package/dist/assets/RotationCcwA.d.ts.map +1 -0
  21. package/dist/assets/RotationCcwB.d.ts +1 -0
  22. package/dist/assets/RotationCcwB.d.ts.map +1 -0
  23. package/dist/assets/RotationCcwC.d.ts +1 -0
  24. package/dist/assets/RotationCcwC.d.ts.map +1 -0
  25. package/dist/assets/RotationCw.d.ts +1 -0
  26. package/dist/assets/RotationCw.d.ts.map +1 -0
  27. package/dist/assets/RotationCwA.d.ts +1 -0
  28. package/dist/assets/RotationCwA.d.ts.map +1 -0
  29. package/dist/assets/RotationCwB.d.ts +1 -0
  30. package/dist/assets/RotationCwB.d.ts.map +1 -0
  31. package/dist/assets/RotationCwC.d.ts +1 -0
  32. package/dist/assets/RotationCwC.d.ts.map +1 -0
  33. package/dist/assets/Run.d.ts +1 -0
  34. package/dist/assets/Run.d.ts.map +1 -0
  35. package/dist/assets/Speed.d.ts +1 -0
  36. package/dist/assets/Speed.d.ts.map +1 -0
  37. package/dist/assets/SpeedFast.d.ts +1 -0
  38. package/dist/assets/SpeedFast.d.ts.map +1 -0
  39. package/dist/assets/SpeedMedium.d.ts +1 -0
  40. package/dist/assets/SpeedMedium.d.ts.map +1 -0
  41. package/dist/assets/SpeedNone.d.ts +1 -0
  42. package/dist/assets/SpeedNone.d.ts.map +1 -0
  43. package/dist/assets/SpeedSlow.d.ts +1 -0
  44. package/dist/assets/SpeedSlow.d.ts.map +1 -0
  45. package/dist/assets/Walk.d.ts +1 -0
  46. package/dist/assets/Walk.d.ts.map +1 -0
  47. package/dist/assets/index.d.ts +1 -0
  48. package/dist/assets/index.d.ts.map +1 -0
  49. package/dist/components/AutoCoreDevPanel.d.ts +144 -0
  50. package/dist/components/AutoCoreDevPanel.d.ts.map +1 -0
  51. package/dist/components/AutoCoreDevPanel.js +1 -0
  52. package/dist/components/BlocklyEditor.d.ts +1 -0
  53. package/dist/components/BlocklyEditor.d.ts.map +1 -0
  54. package/dist/components/BlocklyEditor.js +1 -1
  55. package/dist/components/CodeEditor.d.ts +2 -1
  56. package/dist/components/CodeEditor.d.ts.map +1 -0
  57. package/dist/components/CodeEditor.js +1 -1
  58. package/dist/components/FileList.d.ts +1 -0
  59. package/dist/components/FileList.d.ts.map +1 -0
  60. package/dist/components/FileList.js +1 -1
  61. package/dist/components/FileSelect.d.ts +1 -0
  62. package/dist/components/FileSelect.d.ts.map +1 -0
  63. package/dist/components/FileSelect.js +1 -1
  64. package/dist/components/FitText.d.ts +1 -0
  65. package/dist/components/FitText.d.ts.map +1 -0
  66. package/dist/components/FitText.js +1 -1
  67. package/dist/components/Indicator.d.ts +2 -1
  68. package/dist/components/Indicator.d.ts.map +1 -0
  69. package/dist/components/Indicator.js +1 -1
  70. package/dist/components/IndicatorButton.d.ts +2 -1
  71. package/dist/components/IndicatorButton.d.ts.map +1 -0
  72. package/dist/components/IndicatorButton.js +1 -1
  73. package/dist/components/IndicatorRect.d.ts +2 -1
  74. package/dist/components/IndicatorRect.d.ts.map +1 -0
  75. package/dist/components/JogPanel.d.ts +1 -0
  76. package/dist/components/JogPanel.d.ts.map +1 -0
  77. package/dist/components/Lamp.d.ts +2 -1
  78. package/dist/components/Lamp.d.ts.map +1 -0
  79. package/dist/components/Lamp.js +1 -1
  80. package/dist/components/Osk.d.ts +1 -0
  81. package/dist/components/Osk.d.ts.map +1 -0
  82. package/dist/components/Osk.js +1 -1
  83. package/dist/components/OskDialog.d.ts +1 -0
  84. package/dist/components/OskDialog.d.ts.map +1 -0
  85. package/dist/components/ProgressBarWithValue.d.ts +1 -0
  86. package/dist/components/ProgressBarWithValue.d.ts.map +1 -0
  87. package/dist/components/ProgressBarWithValue.js +1 -1
  88. package/dist/components/TextInput.d.ts +62 -103
  89. package/dist/components/TextInput.d.ts.map +1 -0
  90. package/dist/components/TextInput.js +1 -1
  91. package/dist/components/ToggleGroup.d.ts +2 -1
  92. package/dist/components/ToggleGroup.d.ts.map +1 -0
  93. package/dist/components/ToggleGroup.js +1 -1
  94. package/dist/components/ValueDisplay.d.ts +3 -2
  95. package/dist/components/ValueDisplay.d.ts.map +1 -0
  96. package/dist/components/ValueDisplay.js +1 -1
  97. package/dist/components/ValueIndicator.d.ts +2 -1
  98. package/dist/components/ValueIndicator.d.ts.map +1 -0
  99. package/dist/components/ValueIndicator.js +1 -1
  100. package/dist/components/ValueInput.d.ts +2 -1
  101. package/dist/components/ValueInput.d.ts.map +1 -0
  102. package/dist/components/ValueInput.js +1 -1
  103. package/dist/core/ActionMode.d.ts +1 -0
  104. package/dist/core/ActionMode.d.ts.map +1 -0
  105. package/dist/core/AutoCoreTagContext.d.ts +98 -0
  106. package/dist/core/AutoCoreTagContext.d.ts.map +1 -0
  107. package/dist/core/AutoCoreTagContext.js +1 -0
  108. package/dist/core/AutoCoreTagTypes.d.ts +283 -0
  109. package/dist/core/AutoCoreTagTypes.d.ts.map +1 -0
  110. package/dist/core/AutoCoreTagTypes.js +1 -0
  111. package/dist/core/CoreStreamTypes.d.ts +345 -0
  112. package/dist/core/CoreStreamTypes.d.ts.map +1 -0
  113. package/dist/core/CoreStreamTypes.js +1 -0
  114. package/dist/core/EventEmitterContext.d.ts +113 -202
  115. package/dist/core/EventEmitterContext.d.ts.map +1 -0
  116. package/dist/core/EventEmitterContext.js +1 -1
  117. package/dist/core/IndicatorButtonState.d.ts +1 -0
  118. package/dist/core/IndicatorButtonState.d.ts.map +1 -0
  119. package/dist/core/IndicatorColor.d.ts +1 -0
  120. package/dist/core/IndicatorColor.d.ts.map +1 -0
  121. package/dist/core/MaskPatterns.d.ts +1 -0
  122. package/dist/core/MaskPatterns.d.ts.map +1 -0
  123. package/dist/core/NumerableTypes.d.ts +1 -0
  124. package/dist/core/NumerableTypes.d.ts.map +1 -0
  125. package/dist/core/NumerableTypes.js +1 -1
  126. package/dist/core/PositionContext.d.ts +1 -1
  127. package/dist/core/PositionContext.d.ts.map +1 -0
  128. package/dist/core/UniqueId.d.ts +1 -0
  129. package/dist/core/UniqueId.d.ts.map +1 -0
  130. package/dist/core/ValueSimulator.d.ts +2 -1
  131. package/dist/core/ValueSimulator.d.ts.map +1 -0
  132. package/dist/core/ValueSimulator.js +1 -1
  133. package/dist/core/hoc.d.ts +1 -0
  134. package/dist/core/hoc.d.ts.map +1 -0
  135. package/dist/core/hoc.js +1 -1
  136. package/dist/hooks/adsHooks.d.ts +1 -0
  137. package/dist/hooks/adsHooks.d.ts.map +1 -0
  138. package/dist/hooks/adsHooks.js +1 -1
  139. package/dist/hooks/commandHooks.d.ts +4 -3
  140. package/dist/hooks/commandHooks.d.ts.map +1 -0
  141. package/dist/hooks/commandHooks.js +1 -1
  142. package/dist/hooks/index.d.ts +1 -0
  143. package/dist/hooks/index.d.ts.map +1 -0
  144. package/dist/hooks/useAutoCoreTag.d.ts +26 -0
  145. package/dist/hooks/useAutoCoreTag.d.ts.map +1 -0
  146. package/dist/hooks/useAutoCoreTag.js +1 -0
  147. package/dist/hooks/useScaledValue.d.ts +1 -0
  148. package/dist/hooks/useScaledValue.d.ts.map +1 -0
  149. package/dist/hooks/useScaledValue.js +1 -1
  150. package/dist/hub/CommandMessage.d.ts +19 -9
  151. package/dist/hub/CommandMessage.d.ts.map +1 -0
  152. package/dist/hub/CommandMessage.js +1 -1
  153. package/dist/hub/DebugPanel.d.ts +31 -0
  154. package/dist/hub/DebugPanel.d.ts.map +1 -0
  155. package/dist/hub/DebugPanel.js +1 -0
  156. package/dist/hub/HubBase.d.ts +85 -130
  157. package/dist/hub/HubBase.d.ts.map +1 -0
  158. package/dist/hub/HubBase.js +1 -1
  159. package/dist/hub/HubSimulate.d.ts +42 -8
  160. package/dist/hub/HubSimulate.d.ts.map +1 -0
  161. package/dist/hub/HubSimulate.js +1 -1
  162. package/dist/hub/HubTauri.d.ts +25 -60
  163. package/dist/hub/HubTauri.d.ts.map +1 -0
  164. package/dist/hub/HubTauri.js +1 -1
  165. package/dist/hub/HubWebSocket.d.ts +34 -17
  166. package/dist/hub/HubWebSocket.d.ts.map +1 -0
  167. package/dist/hub/HubWebSocket.js +1 -1
  168. package/dist/hub/debug.d.ts +23 -0
  169. package/dist/hub/debug.d.ts.map +1 -0
  170. package/dist/hub/debug.js +1 -0
  171. package/dist/hub/index.d.ts +20 -4
  172. package/dist/hub/index.d.ts.map +1 -0
  173. package/dist/hub/index.js +1 -1
  174. package/package.json +32 -27
  175. package/readme.md +193 -22
  176. package/src/components/AutoCoreDevPanel.tsx +414 -0
  177. package/src/components/CodeEditor.tsx +2 -2
  178. package/src/components/FileList.tsx +7 -6
  179. package/src/components/FileSelect.tsx +2 -1
  180. package/src/components/Indicator.tsx +2 -2
  181. package/src/components/IndicatorButton.tsx +2 -2
  182. package/src/components/IndicatorRect.tsx +2 -2
  183. package/src/components/Lamp.tsx +3 -3
  184. package/src/components/TextInput.tsx +159 -240
  185. package/src/components/ToggleGroup.tsx +3 -3
  186. package/src/components/ValueDisplay.tsx +4 -4
  187. package/src/components/ValueIndicator.tsx +2 -2
  188. package/src/components/ValueInput.tsx +2 -2
  189. package/src/core/ActionMode.ts +1 -1
  190. package/src/core/AutoCoreTagContext.tsx +615 -0
  191. package/src/core/AutoCoreTagTypes.ts +334 -0
  192. package/src/core/CoreStreamTypes.ts +512 -0
  193. package/src/core/EventEmitterContext.tsx +257 -281
  194. package/src/core/IndicatorButtonState.ts +1 -1
  195. package/src/core/ValueSimulator.ts +2 -2
  196. package/src/core/hoc.tsx +1 -1
  197. package/src/hooks/adsHooks.tsx +21 -22
  198. package/src/hooks/commandHooks.tsx +23 -19
  199. package/src/hooks/index.ts +1 -1
  200. package/src/hooks/useAutoCoreTag.ts +103 -0
  201. package/src/hooks/useScaledValue.tsx +1 -1
  202. package/src/hub/CommandMessage.ts +71 -19
  203. package/src/hub/DebugPanel.ts +280 -0
  204. package/src/hub/HubBase.ts +147 -223
  205. package/src/hub/HubSimulate.ts +93 -24
  206. package/src/hub/HubTauri.ts +87 -96
  207. package/src/hub/HubWebSocket.ts +133 -158
  208. package/src/hub/debug.ts +211 -0
  209. package/src/hub/index.ts +49 -39
  210. package/tsconfig.json +43 -28
  211. package/docs/classes/components_BlocklyEditor.BlocklyEditor.html +0 -124
  212. package/docs/classes/components_CodeEditor.CodeEditor.html +0 -128
  213. package/docs/classes/components_JogPanel.JogPanel.html +0 -138
  214. package/docs/classes/components_Lamp.Lamp.html +0 -105
  215. package/docs/classes/components_TextInput.TextInput.html +0 -115
  216. package/docs/classes/components_ValueIndicator.ValueIndicator.html +0 -119
  217. package/docs/classes/components_ValueInput.ValueInput.html +0 -113
  218. package/docs/classes/hub_HubWebSocket.HubWebSocket.html +0 -106
  219. package/docs/enums/components_JogPanel.JogDistanceAction.html +0 -5
  220. package/docs/enums/components_JogPanel.JogPanelAction.html +0 -18
  221. package/docs/enums/components_JogPanel.JogSpeedAction.html +0 -5
  222. package/docs/enums/core_ActionMode.ActionMode.html +0 -6
  223. package/docs/enums/core_IndicatorColor.IndicatorColor.html +0 -23
  224. package/docs/functions/assets_BlocklyLogo.default.html +0 -1
  225. package/docs/functions/assets_Distance.default.html +0 -1
  226. package/docs/functions/assets_JogLong.default.html +0 -1
  227. package/docs/functions/assets_JogMedium.default.html +0 -1
  228. package/docs/functions/assets_JogShort.default.html +0 -1
  229. package/docs/functions/assets_PythonLogo.default.html +0 -1
  230. package/docs/functions/assets_Rotation3D.default.html +0 -1
  231. package/docs/functions/assets_RotationCcw.default.html +0 -1
  232. package/docs/functions/assets_RotationCcwA.default.html +0 -1
  233. package/docs/functions/assets_RotationCcwB.default.html +0 -1
  234. package/docs/functions/assets_RotationCcwC.default.html +0 -1
  235. package/docs/functions/assets_RotationCw.default.html +0 -1
  236. package/docs/functions/assets_RotationCwA.default.html +0 -1
  237. package/docs/functions/assets_RotationCwB.default.html +0 -1
  238. package/docs/functions/assets_RotationCwC.default.html +0 -1
  239. package/docs/functions/assets_Run.default.html +0 -1
  240. package/docs/functions/assets_Speed.default.html +0 -1
  241. package/docs/functions/assets_SpeedFast.default.html +0 -1
  242. package/docs/functions/assets_SpeedMedium.default.html +0 -1
  243. package/docs/functions/assets_SpeedNone.default.html +0 -1
  244. package/docs/functions/assets_SpeedSlow.default.html +0 -1
  245. package/docs/functions/assets_Walk.default.html +0 -1
  246. package/docs/functions/components_BlocklyEditor.createCustomToolbox.html +0 -6
  247. package/docs/functions/components_FileList.FileList.html +0 -21
  248. package/docs/functions/components_FitText.FitText.html +0 -8
  249. package/docs/functions/components_ToggleGroup.ToggleGroup.html +0 -5
  250. package/docs/interfaces/components_JogPanel.JogPanelButtonDefinition.html +0 -5
  251. package/docs/interfaces/components_ToggleGroup.ToggleGroupProps.html +0 -618
  252. package/docs/interfaces/core_IndicatorButtonState.IndicatorButtonState.html +0 -10
  253. package/docs/interfaces/hub_CommandMessage.CommandMessage.html +0 -6
  254. package/docs/interfaces/hub_CommandMessage.CommandMessageResult.html +0 -4
  255. package/docs/modules/assets.html +0 -23
  256. package/docs/modules/assets_BlocklyLogo.html +0 -2
  257. package/docs/modules/assets_Distance.html +0 -2
  258. package/docs/modules/assets_JogLong.html +0 -2
  259. package/docs/modules/assets_JogMedium.html +0 -2
  260. package/docs/modules/assets_JogShort.html +0 -2
  261. package/docs/modules/assets_PythonLogo.html +0 -2
  262. package/docs/modules/assets_Rotation3D.html +0 -2
  263. package/docs/modules/assets_RotationCcw.html +0 -2
  264. package/docs/modules/assets_RotationCcwA.html +0 -2
  265. package/docs/modules/assets_RotationCcwB.html +0 -2
  266. package/docs/modules/assets_RotationCcwC.html +0 -2
  267. package/docs/modules/assets_RotationCw.html +0 -2
  268. package/docs/modules/assets_RotationCwA.html +0 -2
  269. package/docs/modules/assets_RotationCwB.html +0 -2
  270. package/docs/modules/assets_RotationCwC.html +0 -2
  271. package/docs/modules/assets_Run.html +0 -2
  272. package/docs/modules/assets_Speed.html +0 -2
  273. package/docs/modules/assets_SpeedFast.html +0 -2
  274. package/docs/modules/assets_SpeedMedium.html +0 -2
  275. package/docs/modules/assets_SpeedNone.html +0 -2
  276. package/docs/modules/assets_SpeedSlow.html +0 -2
  277. package/docs/modules/assets_Walk.html +0 -2
  278. package/docs/modules/components_BlocklyEditor.html +0 -5
  279. package/docs/modules/components_CodeEditor.html +0 -3
  280. package/docs/modules/components_FileList.html +0 -3
  281. package/docs/modules/components_FitText.html +0 -3
  282. package/docs/modules/components_JogPanel.html +0 -9
  283. package/docs/modules/components_Lamp.html +0 -4
  284. package/docs/modules/components_TextInput.html +0 -2
  285. package/docs/modules/components_ToggleGroup.html +0 -6
  286. package/docs/modules/components_ValueIndicator.html +0 -4
  287. package/docs/modules/components_ValueInput.html +0 -2
  288. package/docs/modules/core_ActionMode.html +0 -2
  289. package/docs/modules/core_IndicatorButtonState.html +0 -2
  290. package/docs/modules/core_IndicatorColor.html +0 -2
  291. package/docs/modules/hub_CommandMessage.html +0 -3
  292. package/docs/modules/hub_HubWebSocket.html +0 -2
  293. package/docs/types/components_IndicatorButton.IndicatorButtonOptionsType.html +0 -1
  294. package/docs/variables/components_BlocklyEditor.StandardToolbox.html +0 -1
  295. package/docs/variables/components_JogPanel.DefaultLinearJogButtons.html +0 -2
  296. package/docs/variables/components_JogPanel.DefaultRotationJogButtons.html +0 -2
@@ -2,275 +2,194 @@
2
2
  * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
3
  * Created Date: 2024-03-20 13:05:42
4
4
  * -----
5
- * Last Modified: 2024-05-17 10:04:53
5
+ * Last Modified: 2025-09-09 15:32:12
6
6
  * -----
7
7
  *
8
8
  */
9
9
 
10
-
11
- import React from "react";
12
-
13
- import { InputText, InputTextProps } from 'primereact/inputtext';
10
+ import React, { useEffect, useMemo, useState } from "react";
11
+ import { InputText, type InputTextProps } from "primereact/inputtext";
14
12
  import { Button } from "primereact/button";
13
+ import type { KeyFilterType } from "primereact/keyfilter";
15
14
 
16
- import { EventEmitterContext } from "../core/EventEmitterContext.js";
17
- import { KeyFilterType } from "primereact/keyfilter";
15
+ // Props
16
+ interface TextInputProps extends Omit<InputTextProps, "prefix" | "value" | "onChange"> {
17
+ /** The label for the field (shown in an addon). */
18
+ label?: React.ReactNode;
18
19
 
19
- /**
20
- * Properties of the component.
21
- */
22
- interface TextInputProps extends Omit<InputTextProps, "prefix"> {
20
+ /** Controlled value from parent. */
21
+ value?: string;
23
22
 
24
23
  /**
25
- * The label for the field.
24
+ * PrimeReact key filter (lowercase) or RegExp.
25
+ * Examples: "pint" | "int" | "pnum" | "money" | "num" | "hex" | "email" | "alpha" | "alphanum"
26
26
  */
27
- label : React.ReactNode | undefined;
27
+ keyfilter?: KeyFilterType;
28
28
 
29
+ /** Optional prefix addon before the input. */
30
+ prefix?: React.ReactNode;
29
31
 
30
- /**
31
- * The value for the field.
32
- */
33
- value : string | undefined;
32
+ /** Optional suffix addon after the input. */
33
+ suffix?: React.ReactNode;
34
34
 
35
+ /** Small, advisory text below the field. */
36
+ description?: React.ReactNode;
35
37
 
36
- /**
37
- * Optional filter for key entry. Not a validator, but won't accept keystrokes outside the filter.
38
- * @type {RegExp | "pint" | "int" | "pnum" | "money" | "num" | "hex" | "email" | "alpha" | "alphanum"}
39
- */
40
- keyFilter : KeyFilterType | undefined;
41
-
42
-
43
- /**
44
- * An optional prefix before the data entry field.
45
- */
46
- prefix : React.ReactNode | undefined;
38
+ /** Disable entire control. */
39
+ disabled?: boolean;
47
40
 
48
- /**
49
- * An optional suffix after the data entry field.
50
- */
51
- suffix : React.ReactNode | undefined;
41
+ /** Placeholder string. */
42
+ placeholder?: string;
52
43
 
53
- /**
54
- * A small, advisory text below the field.
55
- */
56
- description : React.ReactNode | undefined;
44
+ /** Called when the user ACCEPTS a new value (Enter or ✔). */
45
+ onValueChanged?(newValue: string): void;
57
46
 
58
- /**
59
- * If true, all functions of the field will be disabled.
60
- */
61
- disabled : boolean | undefined;
62
-
63
- /** Topic on which the value will be dispatched through the user interfave on successful data entry. */
64
- dispatchTopic : string | undefined;
65
-
66
- /**
67
- * Placeholder string to display if the value is empty.
68
- */
69
- placeholder : string | undefined;
70
-
71
- /**
72
- * The user has accepted a new value.
73
- * @param newValue New value accepted by the user.
74
- */
75
- onValueChanged?(newValue: string) : void;
76
- /** Regular expression used to validate the value before it is broadcast */
77
- validator : RegExp;
47
+ /** Regex validation used on accept (not on each keystroke). */
48
+ validator?: RegExp;
78
49
  }
79
50
 
80
- /**
81
- * State variables of the component.
82
- */
83
- interface TextInputState {
84
-
85
- entryValue : string | undefined;
86
- isValid : boolean;
87
- editing : boolean;
51
+ function toStr(v?: string | null) {
52
+ return v ?? "";
88
53
  }
89
54
 
90
-
91
55
  /**
92
- * A convenient field with all the usual features of inputing values.
93
- * Wraps the common features of use of a InputText, p-inputgroup, some icon buttons,
94
- * accepting and rejecting values and keyboard management.
56
+ * A styled text input field with support for labels, prefixes/suffixes,
57
+ * validation, key filters, and accept/reset actions.
58
+ *
59
+ * This component wraps PrimeReact's <InputText> in a p-inputgroup with
60
+ * optional ✔ and ✖ buttons for committing or cancelling edits.
61
+ *
62
+ * Features:
63
+ * - Label, prefix, and suffix addons for context
64
+ * - Optional `keyfilter` for keystroke-level restrictions (PrimeReact presets or RegExp)
65
+ * - Optional `validator` RegExp applied when accepting a value
66
+ * - Calls `onValueChanged(newValue)` only when the user accepts (Enter key or ✔ button)
67
+ * - Escape key or ✖ button reverts to the last accepted value
68
+ * - Controlled input: always provide a string `value` (defaults to `""`)
69
+ *
70
+ * ## Example
71
+ *
72
+ * ```tsx
73
+ * import { useState } from "react";
74
+ * import { TextInput } from "./TextInput";
75
+ *
76
+ * export function ExampleForm() {
77
+ * const [partNumber, setPartNumber] = useState("ADC-0001");
78
+ *
79
+ * return (
80
+ * <TextInput
81
+ * label="Part Number"
82
+ * value={partNumber}
83
+ * onValueChanged={setPartNumber}
84
+ * placeholder="Enter part number"
85
+ * keyfilter="alphanum"
86
+ * validator={/^[A-Z0-9-]+$/}
87
+ * description="Use only uppercase letters, digits, and dashes."
88
+ * prefix={<i className="pi pi-tag" />}
89
+ * />
90
+ * );
91
+ * }
92
+ * ```
95
93
  */
96
- export class TextInput extends React.Component<TextInputProps, TextInputState> {
97
-
98
- // Here's an example of using the Application-wide EventEmitter con
99
- // Define the contextType for the class to access the context
100
- static contextType = EventEmitterContext;
101
- // After specifying contextType, you can declare the context's type for the TypeScript compiler.
102
- // Basically, we're telling TypeScript the type of the context; this line doesn't
103
- // actually do any linking linking to the EventEmitterContext.
104
- declare context: React.ContextType<typeof EventEmitterContext>;
105
-
106
-
107
-
108
-
109
- /**
110
- * Default properties for the component.
111
- */
112
- static defaultProps = {
113
- label : '',
114
- value : undefined,
115
- keyFilter : undefined,
116
- writeTopic : undefined,
117
- onValueChanged : undefined,
118
- description: undefined,
119
- prefix: undefined,
120
- suffix : undefined,
121
- disabled : false,
122
- dispatchTopic : undefined,
123
- placeholder : undefined,
124
- validator : undefined
125
- };
126
-
127
- /**
128
- *
129
- * @param {FooterViewProps} props
130
- */
131
- constructor(props : TextInputProps) {
132
- super(props);
133
- this.state = {
134
- entryValue : props.value,
135
- isValid : props.value !== undefined ? this.validateValue(props.value) : false,
136
- editing : false
137
- };
94
+ export const TextInput: React.FC<TextInputProps> = (props) => {
95
+ const {
96
+ label,
97
+ value,
98
+ keyfilter, // <- keep lowercase for PrimeReact
99
+ prefix,
100
+ suffix,
101
+ description,
102
+ disabled = false,
103
+ placeholder,
104
+ onValueChanged,
105
+ validator,
106
+ // DO NOT forward custom props below to the <InputText>
107
+ // Everything else is safe to spread.
108
+ ...restInputProps
109
+ } = props;
110
+
111
+
112
+ // Local edit buffer & validity; parent value is the source of truth after "accept".
113
+ const [entryValue, setEntryValue] = useState<string>(toStr(value));
114
+ const [editing, setEditing] = useState<boolean>(false);
115
+ const [isValid, setIsValid] = useState<boolean>(value ? validateValue(value, validator) : true);
116
+
117
+ // Sync incoming prop value (e.g., external changes/reset)
118
+ useEffect(() => {
119
+ setEntryValue(toStr(value));
120
+ setEditing(false);
121
+ setIsValid(value ? validateValue(value, validator) : true);
122
+ }, [value, validator]);
123
+
124
+ // Validate only when asked to accept
125
+ function validateValue(val: string, re?: RegExp) {
126
+ if (!re) return true;
127
+ return re.test(val);
138
128
  }
139
129
 
140
- /**
141
- * The component has been loaded into the DOM.
142
- */
143
- componentDidMount() {
144
- }
145
-
146
-
147
- componentDidUpdate(prevProps: TextInputProps) {
148
- // Check if the value prop has changed
149
- if (prevProps.value !== this.props.value) {
150
- this.setState({
151
- entryValue: this.props.value,
152
- editing: false
153
- });
154
- }
155
- }
156
-
157
-
158
- /**
159
- * Check the new value against the validator RegEx, if one was specified.
160
- * @param val The new value.
161
- * @returns True if no validator specified or the value is valid, false if not valid.
162
- */
163
- private validateValue = (val : string) => {
164
-
165
- if (this.props.validator !== undefined && this.props.validator !== null) {
166
- return this.props.validator.test(val);
167
- }
168
- else {
169
- return true;
170
- }
171
-
172
- };
173
-
130
+ function accept() {
131
+ const val = entryValue;
132
+ const ok = validateValue(val, validator);
133
+ setIsValid(ok);
134
+ if (!ok) return;
174
135
 
175
- /**
176
- * The user has elected to accept the input value. Validate and store, if valid.
177
- */
178
- private onAcceptValue() {
179
- if (this.state.entryValue !== undefined ) {
180
- if (this.validateValue(this.state.entryValue) ) {
181
- this.setState({isValid : true, editing : false});
182
-
183
- if (this.props.onValueChanged)
184
- this.props.onValueChanged(this.state.entryValue);
185
-
186
- if (this.props.dispatchTopic !== undefined) {
187
- this.context.dispatch({topic: this.props.dispatchTopic, payload:this.state.entryValue});
188
- }
189
-
190
- }
191
- else {
192
- this.setState({isValid : false});
193
- }
194
- }
195
- else {
196
- this.setState({isValid: false});
197
- }
136
+ setEditing(false);
137
+ onValueChanged?.(val);
198
138
  }
199
139
 
200
- /**
201
- * The user wishes to reset/cancel the previous value.
202
- */
203
- private onResetValue() {
204
- this.setState({
205
- entryValue: this.props.value,
206
- isValid: this.props.value !== undefined ? this.validateValue(this.props.value) : false,
207
- editing : false
208
- });
140
+ function reset() {
141
+ const v = toStr(value);
142
+ setEntryValue(v);
143
+ setEditing(false);
144
+ setIsValid(v ? validateValue(v, validator) : true);
209
145
  }
210
146
 
211
-
212
- render() {
213
-
214
- const { prefix, ...restProps} = this.props;
215
-
216
- return(
217
- <div>
218
- <div className="p-inputgroup flex-1" >
219
- <span className="p-inputgroup-addon">
220
- {this.props.label}
221
- </span>
222
- { this.props.prefix !== undefined &&
223
- <span className="p-inputgroup-addon">
224
- {this.props.prefix}
225
- </span>
226
- }
227
- <InputText
228
- {...restProps}
229
- keyfilter={this.props.keyFilter}
230
- placeholder={this.props.placeholder}
231
- value={this.state.entryValue}
232
- onChange={(e) => {this.setState({entryValue: e.target.value, editing : true})} }
233
- className={this.state.isValid ? '' : 'p-invalid'}
234
- onKeyDown={(e) => {
235
- if (e.key === 'Enter') {
236
- this.onAcceptValue();
237
- }
238
- else if (e.key === 'Escape') {
239
- this.onResetValue();
240
- }
241
- }}
242
- disabled={this.props.disabled}
243
- />
244
- { this.props.suffix !== undefined &&
245
- <span className="p-inputgroup-addon">
246
- {this.props.suffix}
247
- </span>
248
- }
249
- <Button
250
- icon="pi pi-check"
251
- disabled={this.props.disabled || !this.state.editing}
252
- className="p-button-success"
253
- onClick={() => this.onAcceptValue()}
254
- visible={this.state.editing}
255
- />
256
-
257
- <Button
258
- icon="pi pi-times"
259
- disabled={this.props.disabled || !this.state.editing}
260
- className="p-button-danger"
261
- onClickCapture={()=>this.onResetValue()}
262
- visible={this.state.editing}
263
- />
264
- </div>
265
-
266
- {this.props.description !== undefined &&
267
- <small>{this.props.description}</small>
268
- }
269
-
270
-
147
+ // Keep the DOM value a string at all times (no uncontrolled→controlled flip)
148
+ const domValue = useMemo(() => toStr(entryValue), [entryValue]);
149
+
150
+ return (
151
+ <div>
152
+ <div className="p-inputgroup flex-1">
153
+ <span className="p-inputgroup-addon">{label}</span>
154
+
155
+ {prefix !== undefined && <span className="p-inputgroup-addon">{prefix}</span>}
156
+
157
+ <InputText
158
+ {...restInputProps}
159
+ keyfilter={keyfilter}
160
+ placeholder={placeholder}
161
+ value={domValue}
162
+ onChange={(e) => {
163
+ setEntryValue(e.target.value);
164
+ setEditing(true);
165
+ }}
166
+ className={isValid ? restInputProps.className ?? "" : `${restInputProps.className ?? ""} p-invalid`}
167
+ onKeyDown={(e) => {
168
+ if (e.key === "Enter") accept();
169
+ else if (e.key === "Escape") reset();
170
+ }}
171
+ disabled={disabled}
172
+ />
173
+
174
+ {suffix !== undefined && <span className="p-inputgroup-addon">{suffix}</span>}
175
+
176
+ <Button
177
+ icon="pi pi-check"
178
+ disabled={disabled || !editing}
179
+ className="p-button-success"
180
+ onClick={accept}
181
+ visible={editing}
182
+ />
183
+ <Button
184
+ icon="pi pi-times"
185
+ disabled={disabled || !editing}
186
+ className="p-button-danger"
187
+ onClick={reset}
188
+ visible={editing}
189
+ />
271
190
  </div>
272
191
 
273
- );
274
- }
275
-
276
- }
192
+ {description !== undefined && <small>{description}</small>}
193
+ </div>
194
+ );
195
+ };
@@ -2,14 +2,14 @@
2
2
  * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
3
  * Created Date: 2024-03-12 10:14:48
4
4
  * -----
5
- * Last Modified: 2024-04-29 10:43:49
5
+ * Last Modified: 2025-09-05 14:51:30
6
6
  * -----
7
7
  *
8
8
  */
9
9
 
10
10
  import React, { useState, useEffect, useContext } from 'react';
11
- import { SelectButton, SelectButtonProps } from 'primereact/selectbutton';
12
- import {SelectItemOptionsType} from "primereact/selectitem";
11
+ import { SelectButton, type SelectButtonProps } from 'primereact/selectbutton';
12
+ import type {SelectItemOptionsType} from "primereact/selectitem";
13
13
 
14
14
  import { EventEmitterContext} from '../core/EventEmitterContext';
15
15
  import {IndicatorColor} from "../core/IndicatorColor";
@@ -2,7 +2,7 @@
2
2
  * Copyright (C) 2024 Automated Design Corp. All Rights Reserved.
3
3
  * Created Date: 2024-01-16 14:17:02
4
4
  * -----
5
- * Last Modified: 2024-05-01 12:14:27
5
+ * Last Modified: 2025-09-05 14:51:23
6
6
  * Modified By: ADC
7
7
  * -----
8
8
  *
@@ -14,9 +14,9 @@ import { Component } from 'react';
14
14
  //import useFitText from 'use-fit-text';
15
15
  import { format as numerableFormat } from 'numerable';
16
16
  import clsx from 'clsx';
17
- import { EventEmitterContext, EventEmitterContextType } from '../core/EventEmitterContext';
17
+ import { EventEmitterContext, type EventEmitterContextType } from '../core/EventEmitterContext';
18
18
 
19
- import { IPositionContext } from '../core/PositionContext';
19
+ import type { IPositionContext } from '../core/PositionContext';
20
20
  import type { NumerableFormatOptions } from '../core/NumerableTypes';
21
21
 
22
22
  /**
@@ -233,4 +233,4 @@ class ValueDisplay extends Component<Props, State> {
233
233
 
234
234
  }
235
235
 
236
- export { ValueDisplay, NumerableFormatOptions };
236
+ export { ValueDisplay, type NumerableFormatOptions };
@@ -2,7 +2,7 @@
2
2
  * Copyright (C) 2024 Automated Design Corp. All Rights Reserved.
3
3
  * Created Date: 2024-01-16 14:17:02
4
4
  * -----
5
- * Last Modified: 2024-03-22 06:42:57
5
+ * Last Modified: 2025-09-05 14:50:58
6
6
  * Modified By: ADC
7
7
  * -----
8
8
  *
@@ -133,4 +133,4 @@ export class ValueIndicator extends Component<ValueIndicatorProps, ValueIndicato
133
133
  }
134
134
 
135
135
  export default ValueIndicator;
136
- export { NumerableFormatOptions };
136
+ export { type NumerableFormatOptions };
@@ -2,7 +2,7 @@
2
2
  * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
3
  * Created Date: 2024-03-20 13:05:42
4
4
  * -----
5
- * Last Modified: 2024-05-17 10:01:45
5
+ * Last Modified: 2025-09-05 14:50:52
6
6
  * -----
7
7
  *
8
8
  */
@@ -58,7 +58,7 @@
58
58
 
59
59
 
60
60
  import React, { useState, useRef, useEffect, useContext } from 'react';
61
- import { InputNumber, InputNumberProps } from 'primereact/inputnumber';
61
+ import { InputNumber, type InputNumberProps } from 'primereact/inputnumber';
62
62
  import { EventEmitterContext } from "../core/EventEmitterContext";
63
63
  import { Button } from 'primereact/button';
64
64
 
@@ -2,7 +2,7 @@
2
2
  * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
3
  * Created Date: 2024-03-12 10:28:38
4
4
  * -----
5
- * Last Modified: 2024-03-12 10:28:47
5
+ * Last Modified: 2026-01-29 09:31:30
6
6
  * -----
7
7
  *
8
8
  */