@adcops/autocore-react 3.3.9 → 3.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/LICENSE +58 -58
  2. package/additional-docs/AutoCoreTagContext.md +441 -441
  3. package/additional-docs/ButtonApiSpecs.md +48 -48
  4. package/additional-docs/GlobalEventEmitter.md +243 -243
  5. package/additional-docs/general_recommendations.md +22 -22
  6. package/additional-docs/react_performance_notes.md +94 -94
  7. package/dist/assets/svg/blockly_logo.svg +82 -82
  8. package/dist/assets/svg/distance.svg +40 -40
  9. package/dist/assets/svg/python_logo.svg +246 -246
  10. package/dist/assets/svg/rotation_ccw.svg +50 -50
  11. package/dist/assets/svg/rotation_ccw_a.svg +57 -57
  12. package/dist/assets/svg/rotation_ccw_b.svg +57 -57
  13. package/dist/assets/svg/rotation_ccw_c.svg +57 -57
  14. package/dist/assets/svg/rotation_cw.svg +49 -49
  15. package/dist/assets/svg/rotation_cw_a.svg +30 -30
  16. package/dist/assets/svg/rotation_cw_b.svg +30 -30
  17. package/dist/assets/svg/rotation_cw_c.svg +30 -30
  18. package/dist/assets/svg/speed.svg +39 -39
  19. package/dist/components/BlocklyEditor.css +93 -93
  20. package/dist/components/Indicator.js +1 -1
  21. package/dist/components/IndicatorRect.d.ts.map +1 -1
  22. package/dist/components/IndicatorRect.js +1 -1
  23. package/dist/components/JogPanel.css +41 -41
  24. package/dist/components/ProgressBarWithValue.css +27 -27
  25. package/dist/components/TextInput.js +1 -1
  26. package/dist/components/ToggleGroup.js +1 -1
  27. package/dist/components/ValueIndicator.css +29 -31
  28. package/dist/components/ValueInput.js +1 -1
  29. package/dist/components/osk.css +123 -123
  30. package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
  31. package/dist/core/AutoCoreTagContext.js +1 -1
  32. package/dist/hub/HubBase.d.ts +3 -3
  33. package/dist/hub/HubBase.d.ts.map +1 -1
  34. package/dist/hub/HubBase.js +1 -1
  35. package/dist/themes/adc-dark/blue/theme.css +3 -0
  36. package/dist/themes/adc-dark/blue/theme.css.map +1 -1
  37. package/package.json +104 -104
  38. package/readme.md +343 -343
  39. package/src/assets/BlocklyLogo.tsx +27 -27
  40. package/src/assets/Distance.tsx +18 -18
  41. package/src/assets/JogLong.tsx +13 -13
  42. package/src/assets/JogMedium.tsx +13 -13
  43. package/src/assets/JogShort.tsx +13 -13
  44. package/src/assets/PythonLogo.tsx +83 -83
  45. package/src/assets/Rotation3D.tsx +13 -13
  46. package/src/assets/RotationCcw.tsx +33 -33
  47. package/src/assets/RotationCcwA.tsx +45 -45
  48. package/src/assets/RotationCcwB.tsx +45 -45
  49. package/src/assets/RotationCcwC.tsx +45 -45
  50. package/src/assets/RotationCw.tsx +31 -31
  51. package/src/assets/RotationCwA.tsx +42 -42
  52. package/src/assets/RotationCwB.tsx +42 -42
  53. package/src/assets/RotationCwC.tsx +42 -42
  54. package/src/assets/Run.tsx +13 -13
  55. package/src/assets/Speed.tsx +18 -18
  56. package/src/assets/SpeedFast.tsx +13 -13
  57. package/src/assets/SpeedMedium.tsx +13 -13
  58. package/src/assets/SpeedNone.tsx +13 -13
  59. package/src/assets/SpeedSlow.tsx +13 -13
  60. package/src/assets/Walk.tsx +13 -13
  61. package/src/assets/index.ts +22 -22
  62. package/src/assets/svg/blockly_logo.svg +82 -82
  63. package/src/assets/svg/distance.svg +40 -40
  64. package/src/assets/svg/python_logo.svg +246 -246
  65. package/src/assets/svg/rotation_ccw.svg +50 -50
  66. package/src/assets/svg/rotation_ccw_a.svg +57 -57
  67. package/src/assets/svg/rotation_ccw_b.svg +57 -57
  68. package/src/assets/svg/rotation_ccw_c.svg +57 -57
  69. package/src/assets/svg/rotation_cw.svg +49 -49
  70. package/src/assets/svg/rotation_cw_a.svg +30 -30
  71. package/src/assets/svg/rotation_cw_b.svg +30 -30
  72. package/src/assets/svg/rotation_cw_c.svg +30 -30
  73. package/src/assets/svg/speed.svg +39 -39
  74. package/src/components/AutoCoreDevPanel.tsx +414 -414
  75. package/src/components/BlocklyEditor.css +93 -93
  76. package/src/components/BlocklyEditor.tsx +609 -609
  77. package/src/components/CodeEditor.tsx +155 -155
  78. package/src/components/FileList.tsx +390 -390
  79. package/src/components/FileSelect.tsx +128 -128
  80. package/src/components/FitText.tsx +35 -35
  81. package/src/components/Indicator.tsx +188 -188
  82. package/src/components/IndicatorButton.tsx +214 -214
  83. package/src/components/IndicatorRect.tsx +170 -172
  84. package/src/components/JogPanel.css +41 -41
  85. package/src/components/JogPanel.tsx +461 -461
  86. package/src/components/Lamp.tsx +243 -243
  87. package/src/components/Osk.tsx +192 -192
  88. package/src/components/OskDialog.tsx +164 -164
  89. package/src/components/ProgressBarWithValue.css +27 -27
  90. package/src/components/ProgressBarWithValue.tsx +48 -48
  91. package/src/components/TextInput.tsx +195 -195
  92. package/src/components/ToggleGroup.tsx +322 -322
  93. package/src/components/ValueDisplay.tsx +236 -236
  94. package/src/components/ValueIndicator.css +29 -31
  95. package/src/components/ValueIndicator.tsx +135 -135
  96. package/src/components/ValueInput.tsx +368 -368
  97. package/src/components/osk.css +123 -123
  98. package/src/core/ActionMode.ts +19 -19
  99. package/src/core/AutoCoreTagContext.tsx +625 -614
  100. package/src/core/AutoCoreTagTypes.ts +334 -334
  101. package/src/core/CoreStreamTypes.ts +512 -512
  102. package/src/core/EventEmitterContext.tsx +434 -434
  103. package/src/core/IndicatorButtonState.ts +34 -34
  104. package/src/core/IndicatorColor.ts +35 -35
  105. package/src/core/MaskPatterns.ts +87 -87
  106. package/src/core/NumerableTypes.ts +80 -80
  107. package/src/core/PositionContext.ts +59 -59
  108. package/src/core/UniqueId.ts +41 -41
  109. package/src/core/ValueSimulator.ts +166 -166
  110. package/src/core/hoc.tsx +65 -65
  111. package/src/hooks/adsHooks.tsx +287 -287
  112. package/src/hooks/commandHooks.tsx +300 -300
  113. package/src/hooks/index.ts +12 -12
  114. package/src/hooks/useAutoCoreTag.ts +103 -103
  115. package/src/hooks/useScaledValue.tsx +99 -99
  116. package/src/hub/CommandMessage.ts +89 -89
  117. package/src/hub/DebugPanel.ts +307 -307
  118. package/src/hub/HubBase.ts +249 -236
  119. package/src/hub/HubSimulate.ts +124 -124
  120. package/src/hub/HubTauri.ts +140 -140
  121. package/src/hub/HubWebSocket.ts +250 -250
  122. package/src/hub/debug.ts +211 -211
  123. package/src/hub/index.ts +81 -81
  124. package/src/themes/adc-dark/_extensions.scss +166 -166
  125. package/src/themes/adc-dark/_variables.scss +913 -913
  126. package/src/themes/adc-dark/blue/_fonts.scss +23 -23
  127. package/src/themes/adc-dark/blue/adc_theme.scss +31 -31
  128. package/src/themes/adc-dark/blue/theme.scss +14 -14
  129. package/src/themes/theme-base/_colors.scss +17 -17
  130. package/src/themes/theme-base/_common.scss +78 -74
  131. package/src/themes/theme-base/_components.scss +111 -111
  132. package/src/themes/theme-base/_mixins.scss +243 -243
  133. package/src/themes/theme-base/components/button/_button.scss +644 -644
  134. package/src/themes/theme-base/components/button/_speeddial.scss +91 -91
  135. package/src/themes/theme-base/components/button/_splitbutton.scss +358 -358
  136. package/src/themes/theme-base/components/data/_carousel.scss +39 -39
  137. package/src/themes/theme-base/components/data/_datascroller.scss +47 -47
  138. package/src/themes/theme-base/components/data/_datatable.scss +388 -388
  139. package/src/themes/theme-base/components/data/_dataview.scss +47 -47
  140. package/src/themes/theme-base/components/data/_filter.scss +137 -137
  141. package/src/themes/theme-base/components/data/_orderlist.scss +86 -86
  142. package/src/themes/theme-base/components/data/_organizationchart.scss +50 -50
  143. package/src/themes/theme-base/components/data/_paginator.scss +91 -91
  144. package/src/themes/theme-base/components/data/_picklist.scss +73 -73
  145. package/src/themes/theme-base/components/data/_timeline.scss +38 -38
  146. package/src/themes/theme-base/components/data/_tree.scss +184 -184
  147. package/src/themes/theme-base/components/data/_treetable.scss +431 -431
  148. package/src/themes/theme-base/components/file/_fileupload.scss +41 -41
  149. package/src/themes/theme-base/components/input/_autocomplete.scss +94 -94
  150. package/src/themes/theme-base/components/input/_calendar.scss +251 -251
  151. package/src/themes/theme-base/components/input/_cascadeselect.scss +107 -107
  152. package/src/themes/theme-base/components/input/_checkbox.scss +181 -181
  153. package/src/themes/theme-base/components/input/_chips.scss +102 -102
  154. package/src/themes/theme-base/components/input/_colorpicker.scss +17 -17
  155. package/src/themes/theme-base/components/input/_dropdown.scss +252 -252
  156. package/src/themes/theme-base/components/input/_editor.scss +122 -122
  157. package/src/themes/theme-base/components/input/_iconfield.scss +9 -9
  158. package/src/themes/theme-base/components/input/_inputgroup.scss +74 -74
  159. package/src/themes/theme-base/components/input/_inputicon.scss +14 -14
  160. package/src/themes/theme-base/components/input/_inputnumber.scss +4 -4
  161. package/src/themes/theme-base/components/input/_inputotp.scss +10 -10
  162. package/src/themes/theme-base/components/input/_inputswitch.scss +99 -99
  163. package/src/themes/theme-base/components/input/_inputtext.scss +101 -101
  164. package/src/themes/theme-base/components/input/_listbox.scss +138 -138
  165. package/src/themes/theme-base/components/input/_mention.scss +30 -30
  166. package/src/themes/theme-base/components/input/_multiselect.scss +278 -278
  167. package/src/themes/theme-base/components/input/_password.scss +32 -32
  168. package/src/themes/theme-base/components/input/_radiobutton.scss +169 -169
  169. package/src/themes/theme-base/components/input/_rating.scss +80 -80
  170. package/src/themes/theme-base/components/input/_selectbutton.scss +49 -49
  171. package/src/themes/theme-base/components/input/_slider.scss +49 -49
  172. package/src/themes/theme-base/components/input/_togglebutton.scss +99 -99
  173. package/src/themes/theme-base/components/input/_treeselect.scss +151 -151
  174. package/src/themes/theme-base/components/input/_tristatecheckbox.scss +46 -46
  175. package/src/themes/theme-base/components/menu/_breadcrumb.scss +42 -42
  176. package/src/themes/theme-base/components/menu/_contextmenu.scss +39 -39
  177. package/src/themes/theme-base/components/menu/_dock.scss +109 -109
  178. package/src/themes/theme-base/components/menu/_megamenu.scss +141 -141
  179. package/src/themes/theme-base/components/menu/_menu.scss +33 -33
  180. package/src/themes/theme-base/components/menu/_menubar.scss +216 -216
  181. package/src/themes/theme-base/components/menu/_panelmenu.scss +153 -153
  182. package/src/themes/theme-base/components/menu/_slidemenu.scss +60 -60
  183. package/src/themes/theme-base/components/menu/_steps.scss +57 -57
  184. package/src/themes/theme-base/components/menu/_tabmenu.scss +50 -50
  185. package/src/themes/theme-base/components/menu/_tieredmenu.scss +43 -43
  186. package/src/themes/theme-base/components/messages/_inlinemessage.scss +69 -69
  187. package/src/themes/theme-base/components/messages/_message.scss +107 -107
  188. package/src/themes/theme-base/components/messages/_toast.scss +100 -100
  189. package/src/themes/theme-base/components/misc/_avatar.scss +33 -33
  190. package/src/themes/theme-base/components/misc/_badge.scss +76 -76
  191. package/src/themes/theme-base/components/misc/_chip.scss +38 -38
  192. package/src/themes/theme-base/components/misc/_inplace.scss +17 -17
  193. package/src/themes/theme-base/components/misc/_metergroup.scss +80 -80
  194. package/src/themes/theme-base/components/misc/_progressbar.scss +17 -17
  195. package/src/themes/theme-base/components/misc/_scrolltop.scss +24 -24
  196. package/src/themes/theme-base/components/misc/_skeleton.scss +7 -7
  197. package/src/themes/theme-base/components/misc/_tag.scss +39 -39
  198. package/src/themes/theme-base/components/misc/_terminal.scss +12 -12
  199. package/src/themes/theme-base/components/multimedia/_galleria.scss +153 -153
  200. package/src/themes/theme-base/components/multimedia/_image.scss +53 -53
  201. package/src/themes/theme-base/components/overlay/_confirmpopup.scss +72 -72
  202. package/src/themes/theme-base/components/overlay/_dialog.scss +78 -78
  203. package/src/themes/theme-base/components/overlay/_overlaypanel.scss +64 -64
  204. package/src/themes/theme-base/components/overlay/_sidebar.scss +23 -23
  205. package/src/themes/theme-base/components/overlay/_tooltip.scss +33 -33
  206. package/src/themes/theme-base/components/panel/_accordion.scss +118 -118
  207. package/src/themes/theme-base/components/panel/_card.scss +30 -30
  208. package/src/themes/theme-base/components/panel/_divider.scss +30 -30
  209. package/src/themes/theme-base/components/panel/_fieldset.scss +47 -47
  210. package/src/themes/theme-base/components/panel/_panel.scss +47 -47
  211. package/src/themes/theme-base/components/panel/_scrollpanel.scss +10 -10
  212. package/src/themes/theme-base/components/panel/_splitter.scss +23 -23
  213. package/src/themes/theme-base/components/panel/_stepper.scss +136 -136
  214. package/src/themes/theme-base/components/panel/_tabview.scss +147 -147
  215. package/src/themes/theme-base/components/panel/_toolbar.scss +11 -11
  216. package/terser.config.cjs +25 -25
  217. package/todo.md +18 -18
  218. package/tools/build-themes.cjs +65 -65
  219. package/tools/copy-distribution-files.cjs +77 -77
  220. package/tools/minify.cjs +55 -55
  221. package/tsconfig.json +48 -48
  222. package/typedoc.json +12 -12
  223. package/.claude/settings.local.json +0 -7
package/readme.md CHANGED
@@ -1,344 +1,344 @@
1
- # autocore-react
2
-
3
- React components for HTML5 user interfaces that are easy to integrate into any project. autocore-react
4
- targets both the browser and Tauri. The primary focus is HMI applications for machine control, as well
5
- as tasks common to general desktop applications.
6
-
7
- ## Overview
8
-
9
- autocore is ADC's collection of Industry 4.0 (IIOT) libraries. autocore-react focuses on user interface
10
- development.
11
-
12
- autocore-react is the third version of this library, and is a simplification of previous versions. Instead
13
- of relying on dozens of custom controls for integration into HMI applications, autocore-react now leans on
14
- PrimeReact to supply almost all but the most obscure controls, and adds a wrapper to integrate
15
- signals from the backend to the common controls. This allows autocore-react to focus on the additional
16
- features needed for machine-control user interfaces, while PrimeReact excels at development of components.
17
-
18
- ## Installation
19
-
20
- Install from NPM.
21
-
22
- ```
23
- npm install --save @adcops/autocore-react
24
- ```
25
-
26
- ## Quick Start
27
-
28
- ### 1. Define Your Tags
29
-
30
- Create `AutoCoreTags.ts` to define all the tags your application will use:
31
-
32
- ```typescript
33
- import type { TagConfig } from "@adcops/autocore-react/core/AutoCoreTagTypes";
34
-
35
- export const acTagSpec = [
36
- { "tagName": "isControlPowerOk", "domain": "ADS", "symbolName": "GIO.xbControlPowerOk", "valueType": "boolean" },
37
- { "tagName": "motorSpeed", "domain": "ADS", "symbolName": "MAIN.ctx.motor.fSpeed", "valueType": "number" },
38
- { "tagName": "isAutoCycleRunning", "domain": "ADS", "symbolName": "MAIN.ctx.gm.bAutoCycleRunning", "valueType": "boolean" },
39
- { "tagName": "positionScalar", "domain": "MEMORYSTORE", "symbolName": "position_scalar", "valueType": "number", "initialValue": 1.0 }
40
- ] as const satisfies readonly TagConfig[];
41
-
42
- export default acTagSpec;
43
- ```
44
-
45
- ### 2. Create Typed Hooks
46
-
47
- Create `AutoCore.ts` to generate strongly-typed hooks:
48
-
49
- ```typescript
50
- import { acTagSpec } from "./AutoCoreTags";
51
- import { AutoCoreTagContext } from "@adcops/autocore-react/core/AutoCoreTagContext";
52
- import { makeAutoCoreTagHooks } from "@adcops/autocore-react/hooks/useAutoCoreTag";
53
-
54
- export const AutoCoreHooks = makeAutoCoreTagHooks(AutoCoreTagContext, acTagSpec);
55
- ```
56
-
57
-
58
- #### Define Scales (Optional)
59
- For applications that need unit conversion, create `AutoCoreScales.ts` with server-driven scaling:
60
-
61
-
62
- ```tsx
63
- import { ScaleConfig } from "@adcops/autocore-react/core/AutoCoreTagTypes";
64
-
65
- export const acScales = {
66
- position: {
67
- name: "position",
68
- scale: 1.0,
69
- label: "mm",
70
- serverTag: { domain: "GNV", symbolName: "position_scalar" }
71
- },
72
- load: {
73
- name: "load",
74
- scale: 1.0,
75
- label: "N",
76
- serverTag: { domain: "GNV", symbolName: "load_scalar" }
77
- }
78
- } as const satisfies Record<string, ScaleConfig>;
79
- ```
80
-
81
- Note: Server tags now store both scale factor and label as a JSON object: `{ scale: 1.0, label: "mm" }`. Legacy numeric-only values are supported for backward compatibility.
82
-
83
- Next, reference scales in your tag definitions.
84
-
85
- ```tsx
86
- // In AutoCoreTags.ts - add scale property to numeric tags
87
- { "tagName": "pressPosition", "domain": "ADS", "symbolName": "MAIN.ctx.gm.fPressPosition", "valueType": "number", "scale": "position" },
88
- { "tagName": "pressLoad", "domain": "ADS", "symbolName": "MAIN.ctx.gm.fPressLoad", "valueType": "number", "scale": "load" }
89
- ```
90
-
91
- ### 3. Wrap Your App
92
-
93
- Update your `App.tsx` to provide the contexts:
94
-
95
- ```typescript
96
- import React from 'react';
97
- import { PrimeReactProvider } from 'primereact/api';
98
- import { EventEmitterProvider } from "@adcops/autocore-react/core/EventEmitterContext";
99
- import { AutoCoreTagProvider } from "@adcops/autocore-react/core/AutoCoreTagContext";
100
- import { acTagSpec } from "./AutoCoreTags";
101
- import { acScales } from "./AutoCoreScales";
102
-
103
- function App() {
104
- return (
105
- <EventEmitterProvider>
106
- <PrimeReactProvider>
107
- <AutoCoreTagProvider tags={acTagSpec} scales={acScales} eagerRead>
108
- <div className="app-wrapper">
109
- <main className="main-wrapper">
110
- <YourMainContent />
111
- </main>
112
- </div>
113
- </AutoCoreTagProvider>
114
- </PrimeReactProvider>
115
- </EventEmitterProvider>
116
- );
117
- }
118
-
119
- export default App;
120
- ```
121
-
122
- ### 4. Use Tags in Components
123
-
124
- Import your typed hooks and use them in any component:
125
-
126
- ```typescript
127
- import React from 'react';
128
- import { Button } from 'primereact/button';
129
- import { AutoCoreHooks } from './AutoCore';
130
-
131
- export const ControlPanel: React.FC = () => {
132
- // Single tag access
133
- const { value: powerOk, write: setPowerOk } = AutoCoreHooks.useAutoCoreTag("isControlPowerOk");
134
- const { value: motorSpeed, write: setMotorSpeed } = AutoCoreHooks.useAutoCoreTag("motorSpeed");
135
-
136
- // Multiple tag access
137
- const { values } = AutoCoreHooks.useAutoCoreTags(["isControlPowerOk", "isAutoCycleRunning"]);
138
-
139
- // Computed state
140
- const { selected: canStart } = AutoCoreHooks.useAutoCoreSelect(v =>
141
- !!v["isControlPowerOk"] && !v["isAutoCycleRunning"]
142
- );
143
-
144
- return (
145
- <div>
146
- <div>Power OK: {powerOk ? "Yes" : "No"}</div>
147
- <div>Motor Speed: {motorSpeed} RPM</div>
148
-
149
- <Button
150
- label="Start Motor"
151
- disabled={!canStart}
152
- onClick={() => setMotorSpeed(1000)}
153
- />
154
-
155
- <Button
156
- label="Emergency Stop"
157
- severity="danger"
158
- onClick={() => setPowerOk(false)}
159
- />
160
- </div>
161
- );
162
- };
163
- ```
164
-
165
- ### 5. Development Panel (Optional)
166
-
167
- Add a debugging panel for development:
168
-
169
- ```typescript
170
- import { AutoCoreDevPanel } from "@adcops/autocore-react/components/AutoCoreDevPanel";
171
- import { acTagSpec } from "./AutoCoreTags";
172
-
173
- // In your App component:
174
- {process.env.NODE_ENV === 'development' && (
175
- <AutoCoreDevPanel
176
- tags={acTagSpec}
177
- className="fixed bottom-4 right-4 bg-white shadow-lg"
178
- />
179
- )}
180
- ```
181
-
182
- ## AutoCoreTagContext Features
183
-
184
- - **Strongly-typed**: Full TypeScript support with IntelliSense for tag names and value types
185
- - **Global state**: Share tag values across your entire application
186
- - **Real-time updates**: Automatic subscription to server data changes
187
- - **No optimistic updates**: UI always reflects true server state
188
- - **Error handling**: Proper async/await patterns with error feedback
189
- - **Development tools**: Built-in debugging panel for testing
190
-
191
- ## Architecture
192
-
193
- ### Hub (Internal)
194
-
195
- The Hub is an internal abstraction that handles communication with the backend. It automatically
196
- selects the proper pipeline based on the environment: HubTauri for Tauri applications, socket.io
197
- for browser instances, and a simulated backend for development environments.
198
-
199
- **Important**: Applications should not interact with the Hub directly. Instead, use the higher-level
200
- abstractions described below.
201
-
202
- ### EventEmitterContext
203
-
204
- The EventEmitterContext provides a global event system for component communication and backend
205
- interaction through `invoke()`, `subscribe()`, and `dispatch()` methods. This is automatically
206
- available when you wrap your app with `<EventEmitterProvider>`.
207
-
208
- ### AutoCoreTagContext (Recommended)
209
-
210
- For most backend data interactions, use the AutoCoreTagContext system with strongly-typed hooks.
211
- This provides the cleanest, most maintainable approach for managing server state in your components.
212
- See the Quick Start section above for setup and usage.
213
-
214
- ## Development
215
-
216
- We typically have an external Tauri project designed to import and test the autocore-react library. We find that
217
- some issues, particularly Singleton classes and certain resources, may not occur when components are tested
218
- within the same project.
219
-
220
- There are multiple ways to test a "pre-release" or "staging" version of the library before publishing the official version.
221
-
222
- ### Use npm tags to publish a "staging" version
223
-
224
- Use this for a final "pre-flight check" or when testing a serious release candidate. For development with frequent changes, use 'npm link.'
225
-
226
- When you publish a package to npm, it automatically assigns the latest tag to the published version. Most users will install the latest version when they omit a tag/version in the npm install command. To publish a "staging" or pre-release version without affecting users of the latest version, you can use a custom tag, such as next, beta, or staging.
227
-
228
- To publish a "staging" version of your package, you can run:
229
- ```
230
- npm publish --tag staging --access=public
231
- ```
232
-
233
- Note that we have to specify that the access is public because the tag makes this "scoped," which are private by default.
234
-
235
- In the test project, simply install the 'staging' tag version.
236
-
237
- ```
238
- npm install @adcops/autocore-react@staging
239
- ```
240
-
241
- ### npm link
242
-
243
- In the root of the autocore-react project, initiate npm link:
244
-
245
- ```
246
- npm link
247
- ```
248
-
249
- Now, the autocore-react project is being served locally to your machine.
250
-
251
- To test it in an external project, navigate to the root directory of that project.
252
-
253
- ```
254
- npm link @adcops/autocore-react
255
- ```
256
-
257
- Whatever current version of autocore-react will be removed and replaced with links to the
258
- project directory on your machine. The nice thing is that, as you make machines in the
259
- autocore-react project, those changes are reflected immediately in the external project.
260
- The downside is that not every file can be served by npm link in this way. For example,
261
- were there font files and icon resources served from autocore-react, the wouldn't load
262
- into the external project because of CORS limitation. Depending on what you're testing,
263
- this may not matter.
264
-
265
- When done testing, in the external project we simply unlink.
266
-
267
- ```
268
- npm unlink @adcops/autocore-react
269
- ```
270
-
271
- A final consequence is that, were autocore-react installed before using npm link, it will
272
- no longer be installed once unlink. You will once again need to install the latest
273
- published version, if so desired.
274
-
275
- ```
276
- npm install --save @adcops/autocore-react
277
- ```
278
-
279
- ## Image assets
280
-
281
- First, always first check PrimeReact at [primereact.org/icons](https://primereact.org/icons/ "primereact.org/icons") to see if an icon with the
282
- proper meaning or look exists. If so, always prefer use of a built-in PrimeReact icon.
283
-
284
- That being said, the PrimeReact icon library isn't written with the industrial market in mind. We've customized and created additional icons with
285
- specific meaning in industrial use.
286
-
287
- We create the SVGs by starting with an SVG from Material Icons that closely resembles our needs, then modify using InkScape or, more often than not, by adjusting
288
- the path by hand. Once ready, we place the file into `./src/assets/svg`.
289
-
290
- However, since we're not using a bundler, it's much easier and more reliable to import by converting the SVG file
291
- to a .tsx file, making it a component that can be imported in our source file. For that task, we use the command-line version of SVGR.
292
-
293
- The package.json file contains a script for running SVGR properly. Running `npm run convert-assets` will process all .svg files in ./src/assets/svg into
294
- .tsx files located in ./src/assets. To use one of the newly-generated components, simply import as you would any component.
295
-
296
- ```
297
- import { JogLong } from '../assets';
298
-
299
- <JogLong className="distance-selector-button" width={16} height={16} />
300
- ```
301
-
302
- Note that hand-editing out some features out of the TSX file is often required. Because of that, the convert-assests command is set not to
303
- overwrite existing .tsx files. If you need to update a pre-existing .tsx file, delete it first.
304
-
305
- Possible options for SVGR:
306
- https://react-svgr.com/docs/options/
307
-
308
- ## Documentation
309
-
310
- To generate documentation:
311
- ```
312
- npm run generate-docs
313
- ```
314
-
315
- Publishing the package will also regenerate the documentation.
316
-
317
- ## Additional Documentation
318
-
319
- Beyond doc-comments in the code, we provide additional documentation in the additional-docs folder.
320
-
321
- - AutoCoreTagContext Manual: [AutoCoreTagContext Manual](../additional-docs/AutoCoreTagContext.md).
322
- - Button API Specs: [Button API Specs](../additional-docs/ButtonApiSpecs.md).
323
- - Global Event Emitter: [Global Event Emitter](../additional-docs/GlobalEventEmitter.md).
324
-
325
- ## Acknowledgements
326
-
327
- Beyond the obvious, inherent React and TypeScript libraries, autocore-react greatly appreciates the works of
328
- these additional libraries.
329
-
330
- - PrimeReact and PrimeIcons
331
- - numerable
332
- - Simple Keyboard (https://github.com/hodgef/simple-keyboard)
333
- - - We customize Simple Keyboard for cleaner physical keyboard integration.
334
- - Monaco editor
335
- - socket-io
336
- - Tauri
337
-
338
- ## Copyright
339
-
340
- (C) Copyright 2021-2025 Automated Design Corp. All Rights Reserved.
341
-
342
- ## License
343
-
1
+ # autocore-react
2
+
3
+ React components for HTML5 user interfaces that are easy to integrate into any project. autocore-react
4
+ targets both the browser and Tauri. The primary focus is HMI applications for machine control, as well
5
+ as tasks common to general desktop applications.
6
+
7
+ ## Overview
8
+
9
+ autocore is ADC's collection of Industry 4.0 (IIOT) libraries. autocore-react focuses on user interface
10
+ development.
11
+
12
+ autocore-react is the third version of this library, and is a simplification of previous versions. Instead
13
+ of relying on dozens of custom controls for integration into HMI applications, autocore-react now leans on
14
+ PrimeReact to supply almost all but the most obscure controls, and adds a wrapper to integrate
15
+ signals from the backend to the common controls. This allows autocore-react to focus on the additional
16
+ features needed for machine-control user interfaces, while PrimeReact excels at development of components.
17
+
18
+ ## Installation
19
+
20
+ Install from NPM.
21
+
22
+ ```
23
+ npm install --save @adcops/autocore-react
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ### 1. Define Your Tags
29
+
30
+ Create `AutoCoreTags.ts` to define all the tags your application will use:
31
+
32
+ ```typescript
33
+ import type { TagConfig } from "@adcops/autocore-react/core/AutoCoreTagTypes";
34
+
35
+ export const acTagSpec = [
36
+ { "tagName": "isControlPowerOk", "domain": "ADS", "symbolName": "GIO.xbControlPowerOk", "valueType": "boolean" },
37
+ { "tagName": "motorSpeed", "domain": "ADS", "symbolName": "MAIN.ctx.motor.fSpeed", "valueType": "number" },
38
+ { "tagName": "isAutoCycleRunning", "domain": "ADS", "symbolName": "MAIN.ctx.gm.bAutoCycleRunning", "valueType": "boolean" },
39
+ { "tagName": "positionScalar", "domain": "MEMORYSTORE", "symbolName": "position_scalar", "valueType": "number", "initialValue": 1.0 }
40
+ ] as const satisfies readonly TagConfig[];
41
+
42
+ export default acTagSpec;
43
+ ```
44
+
45
+ ### 2. Create Typed Hooks
46
+
47
+ Create `AutoCore.ts` to generate strongly-typed hooks:
48
+
49
+ ```typescript
50
+ import { acTagSpec } from "./AutoCoreTags";
51
+ import { AutoCoreTagContext } from "@adcops/autocore-react/core/AutoCoreTagContext";
52
+ import { makeAutoCoreTagHooks } from "@adcops/autocore-react/hooks/useAutoCoreTag";
53
+
54
+ export const AutoCoreHooks = makeAutoCoreTagHooks(AutoCoreTagContext, acTagSpec);
55
+ ```
56
+
57
+
58
+ #### Define Scales (Optional)
59
+ For applications that need unit conversion, create `AutoCoreScales.ts` with server-driven scaling:
60
+
61
+
62
+ ```tsx
63
+ import { ScaleConfig } from "@adcops/autocore-react/core/AutoCoreTagTypes";
64
+
65
+ export const acScales = {
66
+ position: {
67
+ name: "position",
68
+ scale: 1.0,
69
+ label: "mm",
70
+ serverTag: { domain: "GNV", symbolName: "position_scalar" }
71
+ },
72
+ load: {
73
+ name: "load",
74
+ scale: 1.0,
75
+ label: "N",
76
+ serverTag: { domain: "GNV", symbolName: "load_scalar" }
77
+ }
78
+ } as const satisfies Record<string, ScaleConfig>;
79
+ ```
80
+
81
+ Note: Server tags now store both scale factor and label as a JSON object: `{ scale: 1.0, label: "mm" }`. Legacy numeric-only values are supported for backward compatibility.
82
+
83
+ Next, reference scales in your tag definitions.
84
+
85
+ ```tsx
86
+ // In AutoCoreTags.ts - add scale property to numeric tags
87
+ { "tagName": "pressPosition", "domain": "ADS", "symbolName": "MAIN.ctx.gm.fPressPosition", "valueType": "number", "scale": "position" },
88
+ { "tagName": "pressLoad", "domain": "ADS", "symbolName": "MAIN.ctx.gm.fPressLoad", "valueType": "number", "scale": "load" }
89
+ ```
90
+
91
+ ### 3. Wrap Your App
92
+
93
+ Update your `App.tsx` to provide the contexts:
94
+
95
+ ```typescript
96
+ import React from 'react';
97
+ import { PrimeReactProvider } from 'primereact/api';
98
+ import { EventEmitterProvider } from "@adcops/autocore-react/core/EventEmitterContext";
99
+ import { AutoCoreTagProvider } from "@adcops/autocore-react/core/AutoCoreTagContext";
100
+ import { acTagSpec } from "./AutoCoreTags";
101
+ import { acScales } from "./AutoCoreScales";
102
+
103
+ function App() {
104
+ return (
105
+ <EventEmitterProvider>
106
+ <PrimeReactProvider>
107
+ <AutoCoreTagProvider tags={acTagSpec} scales={acScales} eagerRead>
108
+ <div className="app-wrapper">
109
+ <main className="main-wrapper">
110
+ <YourMainContent />
111
+ </main>
112
+ </div>
113
+ </AutoCoreTagProvider>
114
+ </PrimeReactProvider>
115
+ </EventEmitterProvider>
116
+ );
117
+ }
118
+
119
+ export default App;
120
+ ```
121
+
122
+ ### 4. Use Tags in Components
123
+
124
+ Import your typed hooks and use them in any component:
125
+
126
+ ```typescript
127
+ import React from 'react';
128
+ import { Button } from 'primereact/button';
129
+ import { AutoCoreHooks } from './AutoCore';
130
+
131
+ export const ControlPanel: React.FC = () => {
132
+ // Single tag access
133
+ const { value: powerOk, write: setPowerOk } = AutoCoreHooks.useAutoCoreTag("isControlPowerOk");
134
+ const { value: motorSpeed, write: setMotorSpeed } = AutoCoreHooks.useAutoCoreTag("motorSpeed");
135
+
136
+ // Multiple tag access
137
+ const { values } = AutoCoreHooks.useAutoCoreTags(["isControlPowerOk", "isAutoCycleRunning"]);
138
+
139
+ // Computed state
140
+ const { selected: canStart } = AutoCoreHooks.useAutoCoreSelect(v =>
141
+ !!v["isControlPowerOk"] && !v["isAutoCycleRunning"]
142
+ );
143
+
144
+ return (
145
+ <div>
146
+ <div>Power OK: {powerOk ? "Yes" : "No"}</div>
147
+ <div>Motor Speed: {motorSpeed} RPM</div>
148
+
149
+ <Button
150
+ label="Start Motor"
151
+ disabled={!canStart}
152
+ onClick={() => setMotorSpeed(1000)}
153
+ />
154
+
155
+ <Button
156
+ label="Emergency Stop"
157
+ severity="danger"
158
+ onClick={() => setPowerOk(false)}
159
+ />
160
+ </div>
161
+ );
162
+ };
163
+ ```
164
+
165
+ ### 5. Development Panel (Optional)
166
+
167
+ Add a debugging panel for development:
168
+
169
+ ```typescript
170
+ import { AutoCoreDevPanel } from "@adcops/autocore-react/components/AutoCoreDevPanel";
171
+ import { acTagSpec } from "./AutoCoreTags";
172
+
173
+ // In your App component:
174
+ {process.env.NODE_ENV === 'development' && (
175
+ <AutoCoreDevPanel
176
+ tags={acTagSpec}
177
+ className="fixed bottom-4 right-4 bg-white shadow-lg"
178
+ />
179
+ )}
180
+ ```
181
+
182
+ ## AutoCoreTagContext Features
183
+
184
+ - **Strongly-typed**: Full TypeScript support with IntelliSense for tag names and value types
185
+ - **Global state**: Share tag values across your entire application
186
+ - **Real-time updates**: Automatic subscription to server data changes
187
+ - **No optimistic updates**: UI always reflects true server state
188
+ - **Error handling**: Proper async/await patterns with error feedback
189
+ - **Development tools**: Built-in debugging panel for testing
190
+
191
+ ## Architecture
192
+
193
+ ### Hub (Internal)
194
+
195
+ The Hub is an internal abstraction that handles communication with the backend. It automatically
196
+ selects the proper pipeline based on the environment: HubTauri for Tauri applications, socket.io
197
+ for browser instances, and a simulated backend for development environments.
198
+
199
+ **Important**: Applications should not interact with the Hub directly. Instead, use the higher-level
200
+ abstractions described below.
201
+
202
+ ### EventEmitterContext
203
+
204
+ The EventEmitterContext provides a global event system for component communication and backend
205
+ interaction through `invoke()`, `subscribe()`, and `dispatch()` methods. This is automatically
206
+ available when you wrap your app with `<EventEmitterProvider>`.
207
+
208
+ ### AutoCoreTagContext (Recommended)
209
+
210
+ For most backend data interactions, use the AutoCoreTagContext system with strongly-typed hooks.
211
+ This provides the cleanest, most maintainable approach for managing server state in your components.
212
+ See the Quick Start section above for setup and usage.
213
+
214
+ ## Development
215
+
216
+ We typically have an external Tauri project designed to import and test the autocore-react library. We find that
217
+ some issues, particularly Singleton classes and certain resources, may not occur when components are tested
218
+ within the same project.
219
+
220
+ There are multiple ways to test a "pre-release" or "staging" version of the library before publishing the official version.
221
+
222
+ ### Use npm tags to publish a "staging" version
223
+
224
+ Use this for a final "pre-flight check" or when testing a serious release candidate. For development with frequent changes, use 'npm link.'
225
+
226
+ When you publish a package to npm, it automatically assigns the latest tag to the published version. Most users will install the latest version when they omit a tag/version in the npm install command. To publish a "staging" or pre-release version without affecting users of the latest version, you can use a custom tag, such as next, beta, or staging.
227
+
228
+ To publish a "staging" version of your package, you can run:
229
+ ```
230
+ npm publish --tag staging --access=public
231
+ ```
232
+
233
+ Note that we have to specify that the access is public because the tag makes this "scoped," which are private by default.
234
+
235
+ In the test project, simply install the 'staging' tag version.
236
+
237
+ ```
238
+ npm install @adcops/autocore-react@staging
239
+ ```
240
+
241
+ ### npm link
242
+
243
+ In the root of the autocore-react project, initiate npm link:
244
+
245
+ ```
246
+ npm link
247
+ ```
248
+
249
+ Now, the autocore-react project is being served locally to your machine.
250
+
251
+ To test it in an external project, navigate to the root directory of that project.
252
+
253
+ ```
254
+ npm link @adcops/autocore-react
255
+ ```
256
+
257
+ Whatever current version of autocore-react will be removed and replaced with links to the
258
+ project directory on your machine. The nice thing is that, as you make machines in the
259
+ autocore-react project, those changes are reflected immediately in the external project.
260
+ The downside is that not every file can be served by npm link in this way. For example,
261
+ were there font files and icon resources served from autocore-react, the wouldn't load
262
+ into the external project because of CORS limitation. Depending on what you're testing,
263
+ this may not matter.
264
+
265
+ When done testing, in the external project we simply unlink.
266
+
267
+ ```
268
+ npm unlink @adcops/autocore-react
269
+ ```
270
+
271
+ A final consequence is that, were autocore-react installed before using npm link, it will
272
+ no longer be installed once unlink. You will once again need to install the latest
273
+ published version, if so desired.
274
+
275
+ ```
276
+ npm install --save @adcops/autocore-react
277
+ ```
278
+
279
+ ## Image assets
280
+
281
+ First, always first check PrimeReact at [primereact.org/icons](https://primereact.org/icons/ "primereact.org/icons") to see if an icon with the
282
+ proper meaning or look exists. If so, always prefer use of a built-in PrimeReact icon.
283
+
284
+ That being said, the PrimeReact icon library isn't written with the industrial market in mind. We've customized and created additional icons with
285
+ specific meaning in industrial use.
286
+
287
+ We create the SVGs by starting with an SVG from Material Icons that closely resembles our needs, then modify using InkScape or, more often than not, by adjusting
288
+ the path by hand. Once ready, we place the file into `./src/assets/svg`.
289
+
290
+ However, since we're not using a bundler, it's much easier and more reliable to import by converting the SVG file
291
+ to a .tsx file, making it a component that can be imported in our source file. For that task, we use the command-line version of SVGR.
292
+
293
+ The package.json file contains a script for running SVGR properly. Running `npm run convert-assets` will process all .svg files in ./src/assets/svg into
294
+ .tsx files located in ./src/assets. To use one of the newly-generated components, simply import as you would any component.
295
+
296
+ ```
297
+ import { JogLong } from '../assets';
298
+
299
+ <JogLong className="distance-selector-button" width={16} height={16} />
300
+ ```
301
+
302
+ Note that hand-editing out some features out of the TSX file is often required. Because of that, the convert-assests command is set not to
303
+ overwrite existing .tsx files. If you need to update a pre-existing .tsx file, delete it first.
304
+
305
+ Possible options for SVGR:
306
+ https://react-svgr.com/docs/options/
307
+
308
+ ## Documentation
309
+
310
+ To generate documentation:
311
+ ```
312
+ npm run generate-docs
313
+ ```
314
+
315
+ Publishing the package will also regenerate the documentation.
316
+
317
+ ## Additional Documentation
318
+
319
+ Beyond doc-comments in the code, we provide additional documentation in the additional-docs folder.
320
+
321
+ - AutoCoreTagContext Manual: [AutoCoreTagContext Manual](../additional-docs/AutoCoreTagContext.md).
322
+ - Button API Specs: [Button API Specs](../additional-docs/ButtonApiSpecs.md).
323
+ - Global Event Emitter: [Global Event Emitter](../additional-docs/GlobalEventEmitter.md).
324
+
325
+ ## Acknowledgements
326
+
327
+ Beyond the obvious, inherent React and TypeScript libraries, autocore-react greatly appreciates the works of
328
+ these additional libraries.
329
+
330
+ - PrimeReact and PrimeIcons
331
+ - numerable
332
+ - Simple Keyboard (https://github.com/hodgef/simple-keyboard)
333
+ - - We customize Simple Keyboard for cleaner physical keyboard integration.
334
+ - Monaco editor
335
+ - socket-io
336
+ - Tauri
337
+
338
+ ## Copyright
339
+
340
+ (C) Copyright 2021-2025 Automated Design Corp. All Rights Reserved.
341
+
342
+ ## License
343
+
344
344
  Licensed for use on ADC equipment or within ADC software.