@adcops/autocore-react 3.3.9 → 3.3.10

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 (215) 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/JogPanel.css +41 -41
  21. package/dist/components/ProgressBarWithValue.css +27 -27
  22. package/dist/components/ValueIndicator.css +31 -31
  23. package/dist/components/osk.css +123 -123
  24. package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
  25. package/dist/core/AutoCoreTagContext.js +1 -1
  26. package/dist/hub/HubBase.d.ts +3 -3
  27. package/dist/hub/HubBase.d.ts.map +1 -1
  28. package/dist/hub/HubBase.js +1 -1
  29. package/package.json +104 -104
  30. package/readme.md +343 -343
  31. package/src/assets/BlocklyLogo.tsx +27 -27
  32. package/src/assets/Distance.tsx +18 -18
  33. package/src/assets/JogLong.tsx +13 -13
  34. package/src/assets/JogMedium.tsx +13 -13
  35. package/src/assets/JogShort.tsx +13 -13
  36. package/src/assets/PythonLogo.tsx +83 -83
  37. package/src/assets/Rotation3D.tsx +13 -13
  38. package/src/assets/RotationCcw.tsx +33 -33
  39. package/src/assets/RotationCcwA.tsx +45 -45
  40. package/src/assets/RotationCcwB.tsx +45 -45
  41. package/src/assets/RotationCcwC.tsx +45 -45
  42. package/src/assets/RotationCw.tsx +31 -31
  43. package/src/assets/RotationCwA.tsx +42 -42
  44. package/src/assets/RotationCwB.tsx +42 -42
  45. package/src/assets/RotationCwC.tsx +42 -42
  46. package/src/assets/Run.tsx +13 -13
  47. package/src/assets/Speed.tsx +18 -18
  48. package/src/assets/SpeedFast.tsx +13 -13
  49. package/src/assets/SpeedMedium.tsx +13 -13
  50. package/src/assets/SpeedNone.tsx +13 -13
  51. package/src/assets/SpeedSlow.tsx +13 -13
  52. package/src/assets/Walk.tsx +13 -13
  53. package/src/assets/index.ts +22 -22
  54. package/src/assets/svg/blockly_logo.svg +82 -82
  55. package/src/assets/svg/distance.svg +40 -40
  56. package/src/assets/svg/python_logo.svg +246 -246
  57. package/src/assets/svg/rotation_ccw.svg +50 -50
  58. package/src/assets/svg/rotation_ccw_a.svg +57 -57
  59. package/src/assets/svg/rotation_ccw_b.svg +57 -57
  60. package/src/assets/svg/rotation_ccw_c.svg +57 -57
  61. package/src/assets/svg/rotation_cw.svg +49 -49
  62. package/src/assets/svg/rotation_cw_a.svg +30 -30
  63. package/src/assets/svg/rotation_cw_b.svg +30 -30
  64. package/src/assets/svg/rotation_cw_c.svg +30 -30
  65. package/src/assets/svg/speed.svg +39 -39
  66. package/src/components/AutoCoreDevPanel.tsx +414 -414
  67. package/src/components/BlocklyEditor.css +93 -93
  68. package/src/components/BlocklyEditor.tsx +609 -609
  69. package/src/components/CodeEditor.tsx +155 -155
  70. package/src/components/FileList.tsx +390 -390
  71. package/src/components/FileSelect.tsx +128 -128
  72. package/src/components/FitText.tsx +35 -35
  73. package/src/components/Indicator.tsx +188 -188
  74. package/src/components/IndicatorButton.tsx +214 -214
  75. package/src/components/IndicatorRect.tsx +172 -172
  76. package/src/components/JogPanel.css +41 -41
  77. package/src/components/JogPanel.tsx +461 -461
  78. package/src/components/Lamp.tsx +243 -243
  79. package/src/components/Osk.tsx +192 -192
  80. package/src/components/OskDialog.tsx +164 -164
  81. package/src/components/ProgressBarWithValue.css +27 -27
  82. package/src/components/ProgressBarWithValue.tsx +48 -48
  83. package/src/components/TextInput.tsx +195 -195
  84. package/src/components/ToggleGroup.tsx +322 -322
  85. package/src/components/ValueDisplay.tsx +236 -236
  86. package/src/components/ValueIndicator.css +31 -31
  87. package/src/components/ValueIndicator.tsx +135 -135
  88. package/src/components/ValueInput.tsx +368 -368
  89. package/src/components/osk.css +123 -123
  90. package/src/core/ActionMode.ts +19 -19
  91. package/src/core/AutoCoreTagContext.tsx +625 -614
  92. package/src/core/AutoCoreTagTypes.ts +334 -334
  93. package/src/core/CoreStreamTypes.ts +512 -512
  94. package/src/core/EventEmitterContext.tsx +434 -434
  95. package/src/core/IndicatorButtonState.ts +34 -34
  96. package/src/core/IndicatorColor.ts +35 -35
  97. package/src/core/MaskPatterns.ts +87 -87
  98. package/src/core/NumerableTypes.ts +80 -80
  99. package/src/core/PositionContext.ts +59 -59
  100. package/src/core/UniqueId.ts +41 -41
  101. package/src/core/ValueSimulator.ts +166 -166
  102. package/src/core/hoc.tsx +65 -65
  103. package/src/hooks/adsHooks.tsx +287 -287
  104. package/src/hooks/commandHooks.tsx +300 -300
  105. package/src/hooks/index.ts +12 -12
  106. package/src/hooks/useAutoCoreTag.ts +103 -103
  107. package/src/hooks/useScaledValue.tsx +99 -99
  108. package/src/hub/CommandMessage.ts +89 -89
  109. package/src/hub/DebugPanel.ts +307 -307
  110. package/src/hub/HubBase.ts +249 -236
  111. package/src/hub/HubSimulate.ts +124 -124
  112. package/src/hub/HubTauri.ts +140 -140
  113. package/src/hub/HubWebSocket.ts +250 -250
  114. package/src/hub/debug.ts +211 -211
  115. package/src/hub/index.ts +81 -81
  116. package/src/themes/adc-dark/_extensions.scss +166 -166
  117. package/src/themes/adc-dark/_variables.scss +913 -913
  118. package/src/themes/adc-dark/blue/_fonts.scss +23 -23
  119. package/src/themes/adc-dark/blue/adc_theme.scss +31 -31
  120. package/src/themes/adc-dark/blue/theme.scss +14 -14
  121. package/src/themes/theme-base/_colors.scss +17 -17
  122. package/src/themes/theme-base/_common.scss +74 -74
  123. package/src/themes/theme-base/_components.scss +111 -111
  124. package/src/themes/theme-base/_mixins.scss +243 -243
  125. package/src/themes/theme-base/components/button/_button.scss +644 -644
  126. package/src/themes/theme-base/components/button/_speeddial.scss +91 -91
  127. package/src/themes/theme-base/components/button/_splitbutton.scss +358 -358
  128. package/src/themes/theme-base/components/data/_carousel.scss +39 -39
  129. package/src/themes/theme-base/components/data/_datascroller.scss +47 -47
  130. package/src/themes/theme-base/components/data/_datatable.scss +388 -388
  131. package/src/themes/theme-base/components/data/_dataview.scss +47 -47
  132. package/src/themes/theme-base/components/data/_filter.scss +137 -137
  133. package/src/themes/theme-base/components/data/_orderlist.scss +86 -86
  134. package/src/themes/theme-base/components/data/_organizationchart.scss +50 -50
  135. package/src/themes/theme-base/components/data/_paginator.scss +91 -91
  136. package/src/themes/theme-base/components/data/_picklist.scss +73 -73
  137. package/src/themes/theme-base/components/data/_timeline.scss +38 -38
  138. package/src/themes/theme-base/components/data/_tree.scss +184 -184
  139. package/src/themes/theme-base/components/data/_treetable.scss +431 -431
  140. package/src/themes/theme-base/components/file/_fileupload.scss +41 -41
  141. package/src/themes/theme-base/components/input/_autocomplete.scss +94 -94
  142. package/src/themes/theme-base/components/input/_calendar.scss +251 -251
  143. package/src/themes/theme-base/components/input/_cascadeselect.scss +107 -107
  144. package/src/themes/theme-base/components/input/_checkbox.scss +181 -181
  145. package/src/themes/theme-base/components/input/_chips.scss +102 -102
  146. package/src/themes/theme-base/components/input/_colorpicker.scss +17 -17
  147. package/src/themes/theme-base/components/input/_dropdown.scss +252 -252
  148. package/src/themes/theme-base/components/input/_editor.scss +122 -122
  149. package/src/themes/theme-base/components/input/_iconfield.scss +9 -9
  150. package/src/themes/theme-base/components/input/_inputgroup.scss +74 -74
  151. package/src/themes/theme-base/components/input/_inputicon.scss +14 -14
  152. package/src/themes/theme-base/components/input/_inputnumber.scss +4 -4
  153. package/src/themes/theme-base/components/input/_inputotp.scss +10 -10
  154. package/src/themes/theme-base/components/input/_inputswitch.scss +99 -99
  155. package/src/themes/theme-base/components/input/_inputtext.scss +101 -101
  156. package/src/themes/theme-base/components/input/_listbox.scss +138 -138
  157. package/src/themes/theme-base/components/input/_mention.scss +30 -30
  158. package/src/themes/theme-base/components/input/_multiselect.scss +278 -278
  159. package/src/themes/theme-base/components/input/_password.scss +32 -32
  160. package/src/themes/theme-base/components/input/_radiobutton.scss +169 -169
  161. package/src/themes/theme-base/components/input/_rating.scss +80 -80
  162. package/src/themes/theme-base/components/input/_selectbutton.scss +49 -49
  163. package/src/themes/theme-base/components/input/_slider.scss +49 -49
  164. package/src/themes/theme-base/components/input/_togglebutton.scss +99 -99
  165. package/src/themes/theme-base/components/input/_treeselect.scss +151 -151
  166. package/src/themes/theme-base/components/input/_tristatecheckbox.scss +46 -46
  167. package/src/themes/theme-base/components/menu/_breadcrumb.scss +42 -42
  168. package/src/themes/theme-base/components/menu/_contextmenu.scss +39 -39
  169. package/src/themes/theme-base/components/menu/_dock.scss +109 -109
  170. package/src/themes/theme-base/components/menu/_megamenu.scss +141 -141
  171. package/src/themes/theme-base/components/menu/_menu.scss +33 -33
  172. package/src/themes/theme-base/components/menu/_menubar.scss +216 -216
  173. package/src/themes/theme-base/components/menu/_panelmenu.scss +153 -153
  174. package/src/themes/theme-base/components/menu/_slidemenu.scss +60 -60
  175. package/src/themes/theme-base/components/menu/_steps.scss +57 -57
  176. package/src/themes/theme-base/components/menu/_tabmenu.scss +50 -50
  177. package/src/themes/theme-base/components/menu/_tieredmenu.scss +43 -43
  178. package/src/themes/theme-base/components/messages/_inlinemessage.scss +69 -69
  179. package/src/themes/theme-base/components/messages/_message.scss +107 -107
  180. package/src/themes/theme-base/components/messages/_toast.scss +100 -100
  181. package/src/themes/theme-base/components/misc/_avatar.scss +33 -33
  182. package/src/themes/theme-base/components/misc/_badge.scss +76 -76
  183. package/src/themes/theme-base/components/misc/_chip.scss +38 -38
  184. package/src/themes/theme-base/components/misc/_inplace.scss +17 -17
  185. package/src/themes/theme-base/components/misc/_metergroup.scss +80 -80
  186. package/src/themes/theme-base/components/misc/_progressbar.scss +17 -17
  187. package/src/themes/theme-base/components/misc/_scrolltop.scss +24 -24
  188. package/src/themes/theme-base/components/misc/_skeleton.scss +7 -7
  189. package/src/themes/theme-base/components/misc/_tag.scss +39 -39
  190. package/src/themes/theme-base/components/misc/_terminal.scss +12 -12
  191. package/src/themes/theme-base/components/multimedia/_galleria.scss +153 -153
  192. package/src/themes/theme-base/components/multimedia/_image.scss +53 -53
  193. package/src/themes/theme-base/components/overlay/_confirmpopup.scss +72 -72
  194. package/src/themes/theme-base/components/overlay/_dialog.scss +78 -78
  195. package/src/themes/theme-base/components/overlay/_overlaypanel.scss +64 -64
  196. package/src/themes/theme-base/components/overlay/_sidebar.scss +23 -23
  197. package/src/themes/theme-base/components/overlay/_tooltip.scss +33 -33
  198. package/src/themes/theme-base/components/panel/_accordion.scss +118 -118
  199. package/src/themes/theme-base/components/panel/_card.scss +30 -30
  200. package/src/themes/theme-base/components/panel/_divider.scss +30 -30
  201. package/src/themes/theme-base/components/panel/_fieldset.scss +47 -47
  202. package/src/themes/theme-base/components/panel/_panel.scss +47 -47
  203. package/src/themes/theme-base/components/panel/_scrollpanel.scss +10 -10
  204. package/src/themes/theme-base/components/panel/_splitter.scss +23 -23
  205. package/src/themes/theme-base/components/panel/_stepper.scss +136 -136
  206. package/src/themes/theme-base/components/panel/_tabview.scss +147 -147
  207. package/src/themes/theme-base/components/panel/_toolbar.scss +11 -11
  208. package/terser.config.cjs +25 -25
  209. package/todo.md +18 -18
  210. package/tools/build-themes.cjs +65 -65
  211. package/tools/copy-distribution-files.cjs +77 -77
  212. package/tools/minify.cjs +55 -55
  213. package/tsconfig.json +48 -48
  214. package/typedoc.json +12 -12
  215. package/.claude/settings.local.json +0 -7
@@ -1,103 +1,103 @@
1
- /*
2
- * Copyright (C) 2025 Automated Design Corp.. All Rights Reserved.
3
- * Created Date: 2025-09-05 08:03:32
4
- * -----
5
- * Last Modified: 2026-03-05 06:27:56
6
- * -----
7
- *
8
- */
9
-
10
- /**
11
- * @module hooks/useAutoCoreTag.ts
12
- *
13
- * Factory for generating strongly-typed React hooks to consume AutoCoreTagContext.
14
- */
15
-
16
- import { useCallback, useContext, useMemo } from "react";
17
- import type { BaseContextValue, TagConfig, TagValueMap } from "../core/AutoCoreTagTypes";
18
-
19
- export function makeAutoCoreTagHooks<Spec extends readonly TagConfig[]>(
20
- Context: React.Context<BaseContextValue<TagValueMap<Spec>>>,
21
- tags: Spec
22
- ) {
23
- type VMap = TagValueMap<Spec>;
24
- type TagNames = keyof VMap & string;
25
-
26
- const findCfg = (tagName: string) =>
27
- tags.find(t => t.tagName === tagName) as (Spec[number] | undefined);
28
-
29
- /**
30
- * Access a single tag by name.
31
- * Returns current value, raw value, direct server writer, and tap helper.
32
- */
33
- const useAutoCoreTag = <K extends TagNames>(tagName: K) => {
34
- const { values, rawValues, isLoading, write: ctxWrite, tap: ctxTap } = useContext(Context);
35
-
36
- const cfg = findCfg(tagName as string);
37
- if (!cfg) throw new Error(`useAutoCoreTag: unknown tagName '${String(tagName)}'`);
38
-
39
- const write = useCallback(
40
- (displayValue: VMap[K]) => ctxWrite(tagName, displayValue),
41
- [ctxWrite, tagName]
42
- );
43
-
44
- const tap = useCallback(() => ctxTap?.(tagName), [ctxTap, tagName]);
45
-
46
- return {
47
- value: values[tagName] as VMap[K],
48
- rawValue: rawValues[tagName as string],
49
- write,
50
- tap,
51
- isLoading,
52
- } as const;
53
- };
54
-
55
- /**
56
- * Access multiple tags at once with a bulk writer.
57
- */
58
- const useAutoCoreTags = <K extends TagNames>(tagNames: readonly K[]) => {
59
- const { values, rawValues, isLoading, write: ctxWrite } = useContext(Context);
60
-
61
- const subset = useMemo(
62
- () =>
63
- Object.fromEntries(
64
- tagNames.map(k => [k, values[k] as VMap[K]])
65
- ) as { [P in K]: VMap[P] },
66
- [values, tagNames]
67
- );
68
-
69
- const rawSubset = useMemo(
70
- () =>
71
- Object.fromEntries(
72
- tagNames.map(k => [k, rawValues[k as string]])
73
- ) as { [P in K]: unknown },
74
- [rawValues, tagNames]
75
- );
76
-
77
- const write = useCallback(async (tagName: K, value: VMap[K]) => {
78
- await ctxWrite(tagName, value);
79
- }, [ctxWrite]);
80
-
81
- return { values: subset, rawValues: rawSubset, write, isLoading } as const;
82
- };
83
-
84
- /**
85
- * Compute a derived value from the full tag state.
86
- */
87
- const useAutoCoreSelect = <R>(selector: (all: Readonly<Partial<VMap>>) => R, deps: any[] = []) => {
88
- const { values, isLoading } = useContext(Context);
89
- const selected = useMemo(() => selector(values), [values, ...deps]);
90
- return { selected, isLoading } as const;
91
- };
92
-
93
- /**
94
- * Access scale configurations and update functions.
95
- */
96
- const useScales = () => {
97
- const { scales, updateScale } = useContext(Context);
98
- const getScale = useCallback((scaleName: string) => scales[scaleName], [scales]);
99
- return { scales, updateScale, getScale } as const;
100
- };
101
-
102
- return { useAutoCoreTag, useAutoCoreTags, useAutoCoreSelect, useScales } as const;
103
- }
1
+ /*
2
+ * Copyright (C) 2025 Automated Design Corp.. All Rights Reserved.
3
+ * Created Date: 2025-09-05 08:03:32
4
+ * -----
5
+ * Last Modified: 2026-03-05 06:27:56
6
+ * -----
7
+ *
8
+ */
9
+
10
+ /**
11
+ * @module hooks/useAutoCoreTag.ts
12
+ *
13
+ * Factory for generating strongly-typed React hooks to consume AutoCoreTagContext.
14
+ */
15
+
16
+ import { useCallback, useContext, useMemo } from "react";
17
+ import type { BaseContextValue, TagConfig, TagValueMap } from "../core/AutoCoreTagTypes";
18
+
19
+ export function makeAutoCoreTagHooks<Spec extends readonly TagConfig[]>(
20
+ Context: React.Context<BaseContextValue<TagValueMap<Spec>>>,
21
+ tags: Spec
22
+ ) {
23
+ type VMap = TagValueMap<Spec>;
24
+ type TagNames = keyof VMap & string;
25
+
26
+ const findCfg = (tagName: string) =>
27
+ tags.find(t => t.tagName === tagName) as (Spec[number] | undefined);
28
+
29
+ /**
30
+ * Access a single tag by name.
31
+ * Returns current value, raw value, direct server writer, and tap helper.
32
+ */
33
+ const useAutoCoreTag = <K extends TagNames>(tagName: K) => {
34
+ const { values, rawValues, isLoading, write: ctxWrite, tap: ctxTap } = useContext(Context);
35
+
36
+ const cfg = findCfg(tagName as string);
37
+ if (!cfg) throw new Error(`useAutoCoreTag: unknown tagName '${String(tagName)}'`);
38
+
39
+ const write = useCallback(
40
+ (displayValue: VMap[K]) => ctxWrite(tagName, displayValue),
41
+ [ctxWrite, tagName]
42
+ );
43
+
44
+ const tap = useCallback(() => ctxTap?.(tagName), [ctxTap, tagName]);
45
+
46
+ return {
47
+ value: values[tagName] as VMap[K],
48
+ rawValue: rawValues[tagName as string],
49
+ write,
50
+ tap,
51
+ isLoading,
52
+ } as const;
53
+ };
54
+
55
+ /**
56
+ * Access multiple tags at once with a bulk writer.
57
+ */
58
+ const useAutoCoreTags = <K extends TagNames>(tagNames: readonly K[]) => {
59
+ const { values, rawValues, isLoading, write: ctxWrite } = useContext(Context);
60
+
61
+ const subset = useMemo(
62
+ () =>
63
+ Object.fromEntries(
64
+ tagNames.map(k => [k, values[k] as VMap[K]])
65
+ ) as { [P in K]: VMap[P] },
66
+ [values, tagNames]
67
+ );
68
+
69
+ const rawSubset = useMemo(
70
+ () =>
71
+ Object.fromEntries(
72
+ tagNames.map(k => [k, rawValues[k as string]])
73
+ ) as { [P in K]: unknown },
74
+ [rawValues, tagNames]
75
+ );
76
+
77
+ const write = useCallback(async (tagName: K, value: VMap[K]) => {
78
+ await ctxWrite(tagName, value);
79
+ }, [ctxWrite]);
80
+
81
+ return { values: subset, rawValues: rawSubset, write, isLoading } as const;
82
+ };
83
+
84
+ /**
85
+ * Compute a derived value from the full tag state.
86
+ */
87
+ const useAutoCoreSelect = <R>(selector: (all: Readonly<Partial<VMap>>) => R, deps: any[] = []) => {
88
+ const { values, isLoading } = useContext(Context);
89
+ const selected = useMemo(() => selector(values), [values, ...deps]);
90
+ return { selected, isLoading } as const;
91
+ };
92
+
93
+ /**
94
+ * Access scale configurations and update functions.
95
+ */
96
+ const useScales = () => {
97
+ const { scales, updateScale } = useContext(Context);
98
+ const getScale = useCallback((scaleName: string) => scales[scaleName], [scales]);
99
+ return { scales, updateScale, getScale } as const;
100
+ };
101
+
102
+ return { useAutoCoreTag, useAutoCoreTags, useAutoCoreSelect, useScales } as const;
103
+ }
@@ -1,100 +1,100 @@
1
- /*
2
- * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
- * Created Date: 2024-04-30 11:41:59
4
- * -----
5
- * Last Modified: 2026-01-29 09:33:46
6
- * -----
7
- *
8
- */
9
-
10
-
11
-
12
- import { useCallback, useState, useEffect } from 'react';
13
-
14
- /**
15
- * Multiple millimeters by this constant for inches.
16
- */
17
- export const kMillimeters2Inches: number = 1 / 25.4;
18
-
19
- /**
20
- * Multiply netwons by this constant for pounds.
21
- */
22
- export const kNewtons2Pounds : number = 1 / 4.4482216153;
23
-
24
-
25
- type UseScaledValueReturn = [number, (newValue: number) => void];
26
-
27
- /**
28
- * A custom React hook for converting values between different scales,
29
- * with support for dynamically updating the scale and offset. This hook manages values
30
- * in a base unit and allows for easy conversion to a display unit, updating
31
- * reactively to changes in the conversion factors.
32
- *
33
- * @param initialValue - The initial value in the base unit.
34
- * @param scale - The dynamic scale factor used for conversion to the display unit.
35
- * @param offset - An optional offset applied after scaling (default is 0).
36
- * @returns A tuple containing the display value and a setter function for updating
37
- * the value in the display unit.
38
- *
39
- * @example
40
- * Here's how to use `useScaledValue` in a component that fetches a scale factor from a backend
41
- * and allows the user to input values in a converted scale, which are then handled in a base unit:
42
- *
43
- * ```tsx
44
- * import React, { useState, useEffect } from 'react';
45
- * import { useScaledValue } from './hooks/useScaledValue';
46
- *
47
- * const MeasurementInput: React.FC = () => {
48
- * const [units, setUnits] = useState<number>(1); // Start with a default scale of 1
49
- * const [xPosition, setXPosition] = useScaledValue(0, units);
50
- *
51
- * useEffect(() => {
52
- * async function fetchScale() {
53
- * try {
54
- * // Simulate fetching scale factor from a backend
55
- * const res = await invoke("GNV", "read_value", { group: "ux", key: "kSelectedUnits" });
56
- * setUnits(res.data); // Update scale based on backend response
57
- * } catch (error) {
58
- * console.error('Failed to fetch units', error);
59
- * }
60
- * }
61
- * fetchScale();
62
- * }, []);
63
- *
64
- * return (
65
- * <input
66
- * type="number"
67
- * value={xPosition.toFixed(2)} // Display the value formatted to 2 decimal places
68
- * onChange={(e) => setXPosition(parseFloat(e.target.value))}
69
- * />
70
- * );
71
- * };
72
- *
73
- * export default MeasurementInput;
74
- * ```
75
- *
76
- * In this example, `useScaledValue` is used to manage a measurement input in a dynamic unit system.
77
- * The component fetches the conversion scale from the backend upon component mounting and updates the
78
- * input display accordingly. The user's input is converted back to the base unit before being processed.
79
- */
80
- export function useScaledValue(initialValue: number, scale: number, offset: number = 0): UseScaledValueReturn {
81
- const [baseValue, setBaseValue] = useState<number>(initialValue);
82
- const [displayValue, setDisplayValue] = useState<number>(() => (initialValue * scale) + offset);
83
-
84
- // Update display value whenever baseValue, scale, or offset changes
85
- useEffect(() => {
86
-
87
- // In autocore-react, we multiple to scale incoming values,
88
- // divide to scale outgoing values.
89
- // This is an INCOMING value, so we multiply.
90
-
91
- setDisplayValue((baseValue * scale) + offset);
92
- }, [baseValue, scale, offset]);
93
-
94
- // Function to update baseValue when displayValue changes
95
- const handleSetDisplayValue = useCallback((newValue: number) => {
96
- setBaseValue(newValue);
97
- }, [scale, offset]);
98
-
99
- return [displayValue, handleSetDisplayValue];
1
+ /*
2
+ * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
+ * Created Date: 2024-04-30 11:41:59
4
+ * -----
5
+ * Last Modified: 2026-01-29 09:33:46
6
+ * -----
7
+ *
8
+ */
9
+
10
+
11
+
12
+ import { useCallback, useState, useEffect } from 'react';
13
+
14
+ /**
15
+ * Multiple millimeters by this constant for inches.
16
+ */
17
+ export const kMillimeters2Inches: number = 1 / 25.4;
18
+
19
+ /**
20
+ * Multiply netwons by this constant for pounds.
21
+ */
22
+ export const kNewtons2Pounds : number = 1 / 4.4482216153;
23
+
24
+
25
+ type UseScaledValueReturn = [number, (newValue: number) => void];
26
+
27
+ /**
28
+ * A custom React hook for converting values between different scales,
29
+ * with support for dynamically updating the scale and offset. This hook manages values
30
+ * in a base unit and allows for easy conversion to a display unit, updating
31
+ * reactively to changes in the conversion factors.
32
+ *
33
+ * @param initialValue - The initial value in the base unit.
34
+ * @param scale - The dynamic scale factor used for conversion to the display unit.
35
+ * @param offset - An optional offset applied after scaling (default is 0).
36
+ * @returns A tuple containing the display value and a setter function for updating
37
+ * the value in the display unit.
38
+ *
39
+ * @example
40
+ * Here's how to use `useScaledValue` in a component that fetches a scale factor from a backend
41
+ * and allows the user to input values in a converted scale, which are then handled in a base unit:
42
+ *
43
+ * ```tsx
44
+ * import React, { useState, useEffect } from 'react';
45
+ * import { useScaledValue } from './hooks/useScaledValue';
46
+ *
47
+ * const MeasurementInput: React.FC = () => {
48
+ * const [units, setUnits] = useState<number>(1); // Start with a default scale of 1
49
+ * const [xPosition, setXPosition] = useScaledValue(0, units);
50
+ *
51
+ * useEffect(() => {
52
+ * async function fetchScale() {
53
+ * try {
54
+ * // Simulate fetching scale factor from a backend
55
+ * const res = await invoke("GNV", "read_value", { group: "ux", key: "kSelectedUnits" });
56
+ * setUnits(res.data); // Update scale based on backend response
57
+ * } catch (error) {
58
+ * console.error('Failed to fetch units', error);
59
+ * }
60
+ * }
61
+ * fetchScale();
62
+ * }, []);
63
+ *
64
+ * return (
65
+ * <input
66
+ * type="number"
67
+ * value={xPosition.toFixed(2)} // Display the value formatted to 2 decimal places
68
+ * onChange={(e) => setXPosition(parseFloat(e.target.value))}
69
+ * />
70
+ * );
71
+ * };
72
+ *
73
+ * export default MeasurementInput;
74
+ * ```
75
+ *
76
+ * In this example, `useScaledValue` is used to manage a measurement input in a dynamic unit system.
77
+ * The component fetches the conversion scale from the backend upon component mounting and updates the
78
+ * input display accordingly. The user's input is converted back to the base unit before being processed.
79
+ */
80
+ export function useScaledValue(initialValue: number, scale: number, offset: number = 0): UseScaledValueReturn {
81
+ const [baseValue, setBaseValue] = useState<number>(initialValue);
82
+ const [displayValue, setDisplayValue] = useState<number>(() => (initialValue * scale) + offset);
83
+
84
+ // Update display value whenever baseValue, scale, or offset changes
85
+ useEffect(() => {
86
+
87
+ // In autocore-react, we multiple to scale incoming values,
88
+ // divide to scale outgoing values.
89
+ // This is an INCOMING value, so we multiply.
90
+
91
+ setDisplayValue((baseValue * scale) + offset);
92
+ }, [baseValue, scale, offset]);
93
+
94
+ // Function to update baseValue when displayValue changes
95
+ const handleSetDisplayValue = useCallback((newValue: number) => {
96
+ setBaseValue(newValue);
97
+ }, [scale, offset]);
98
+
99
+ return [displayValue, handleSetDisplayValue];
100
100
  }
@@ -1,89 +1,89 @@
1
- /*
2
- * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
- * Created Date: 2024-04-24 11:47:13
4
- * -----
5
- * Last Modified: 2026-01-29 09:33:54
6
- * -----
7
- *
8
- */
9
-
10
-
11
- // Replaced by a flattened CommandMessage
12
- // /// The result portion of a CommandMessage. The server will
13
- // /// place the result of a command in this portion of the message.
14
- // export interface CommandMessageResult {
15
- // /// The JSON object of the result.
16
- // data: any;
17
- // /// If true, the command was processed successfully.
18
- // success : boolean,
19
- // /// If success is false, this should contain a corresponding error message.
20
- // error_message: string;
21
- // }
22
-
23
-
24
- export enum MessageType {
25
- /// Invalid or no operation. Used for keepalive/ping.
26
- NoOp = 0,
27
-
28
- /// Response to a previous request.
29
- Response = 1,
30
-
31
- /// Read request - module should return data for the specified topic.
32
- Read = 2,
33
-
34
- /// Write request - module should store the provided data.
35
- Write = 3,
36
-
37
- /// Subscribe to updates on a topic.
38
- Subscribe = 4,
39
-
40
- /// Unsubscribe from a topic.
41
- Unsubscribe = 5,
42
-
43
- /// Broadcast message (unsolicited push from module to server or vice versa).
44
- Broadcast = 6,
45
-
46
- /// Heartbeat/keepalive message.
47
- Heartbeat = 7,
48
-
49
- /// Control message (initialize, finalize, configuration).
50
- Control = 8,
51
-
52
- /// Generic request - module parses topic to determine action.
53
- Request = 10,
54
- }
55
-
56
-
57
-
58
- /// CommandMessage is the object passed between the client and server for making requests and
59
- /// responses.
60
- export interface CommandMessage {
61
- /// An id to identify the request. The request ID is managed by the client and will be reflected back.
62
- /// The server will never change the request ID.
63
- transaction_id: number;
64
-
65
- /// Timestamp in milliseconds since UNIX epoch.
66
- /// Set automatically on message creation.
67
- timecode: number,
68
-
69
-
70
- /// Fully-qualified topic name (FQDN).
71
- /// Format: "domain.subtopic.path" e.g., "ads.plc1.GM.stData"
72
- topic: string;
73
-
74
- /// The type/purpose of this message.
75
- message_type: MessageType,
76
-
77
- /// The payload data.
78
- /// - For requests: arguments/parameters
79
- /// - For responses: result data
80
- data?: any;
81
-
82
-
83
- /// Whether the operation was successful (for responses).
84
- success: boolean,
85
-
86
- /// Error message if the operation failed (for responses).
87
- error_message: string,
88
-
89
- }
1
+ /*
2
+ * Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
3
+ * Created Date: 2024-04-24 11:47:13
4
+ * -----
5
+ * Last Modified: 2026-01-29 09:33:54
6
+ * -----
7
+ *
8
+ */
9
+
10
+
11
+ // Replaced by a flattened CommandMessage
12
+ // /// The result portion of a CommandMessage. The server will
13
+ // /// place the result of a command in this portion of the message.
14
+ // export interface CommandMessageResult {
15
+ // /// The JSON object of the result.
16
+ // data: any;
17
+ // /// If true, the command was processed successfully.
18
+ // success : boolean,
19
+ // /// If success is false, this should contain a corresponding error message.
20
+ // error_message: string;
21
+ // }
22
+
23
+
24
+ export enum MessageType {
25
+ /// Invalid or no operation. Used for keepalive/ping.
26
+ NoOp = 0,
27
+
28
+ /// Response to a previous request.
29
+ Response = 1,
30
+
31
+ /// Read request - module should return data for the specified topic.
32
+ Read = 2,
33
+
34
+ /// Write request - module should store the provided data.
35
+ Write = 3,
36
+
37
+ /// Subscribe to updates on a topic.
38
+ Subscribe = 4,
39
+
40
+ /// Unsubscribe from a topic.
41
+ Unsubscribe = 5,
42
+
43
+ /// Broadcast message (unsolicited push from module to server or vice versa).
44
+ Broadcast = 6,
45
+
46
+ /// Heartbeat/keepalive message.
47
+ Heartbeat = 7,
48
+
49
+ /// Control message (initialize, finalize, configuration).
50
+ Control = 8,
51
+
52
+ /// Generic request - module parses topic to determine action.
53
+ Request = 10,
54
+ }
55
+
56
+
57
+
58
+ /// CommandMessage is the object passed between the client and server for making requests and
59
+ /// responses.
60
+ export interface CommandMessage {
61
+ /// An id to identify the request. The request ID is managed by the client and will be reflected back.
62
+ /// The server will never change the request ID.
63
+ transaction_id: number;
64
+
65
+ /// Timestamp in milliseconds since UNIX epoch.
66
+ /// Set automatically on message creation.
67
+ timecode: number,
68
+
69
+
70
+ /// Fully-qualified topic name (FQDN).
71
+ /// Format: "domain.subtopic.path" e.g., "ads.plc1.GM.stData"
72
+ topic: string;
73
+
74
+ /// The type/purpose of this message.
75
+ message_type: MessageType,
76
+
77
+ /// The payload data.
78
+ /// - For requests: arguments/parameters
79
+ /// - For responses: result data
80
+ data?: any;
81
+
82
+
83
+ /// Whether the operation was successful (for responses).
84
+ success: boolean,
85
+
86
+ /// Error message if the operation failed (for responses).
87
+ error_message: string,
88
+
89
+ }