@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.
- package/LICENSE +58 -58
- package/additional-docs/AutoCoreTagContext.md +441 -441
- package/additional-docs/ButtonApiSpecs.md +48 -48
- package/additional-docs/GlobalEventEmitter.md +243 -243
- package/additional-docs/general_recommendations.md +22 -22
- package/additional-docs/react_performance_notes.md +94 -94
- package/dist/assets/svg/blockly_logo.svg +82 -82
- package/dist/assets/svg/distance.svg +40 -40
- package/dist/assets/svg/python_logo.svg +246 -246
- package/dist/assets/svg/rotation_ccw.svg +50 -50
- package/dist/assets/svg/rotation_ccw_a.svg +57 -57
- package/dist/assets/svg/rotation_ccw_b.svg +57 -57
- package/dist/assets/svg/rotation_ccw_c.svg +57 -57
- package/dist/assets/svg/rotation_cw.svg +49 -49
- package/dist/assets/svg/rotation_cw_a.svg +30 -30
- package/dist/assets/svg/rotation_cw_b.svg +30 -30
- package/dist/assets/svg/rotation_cw_c.svg +30 -30
- package/dist/assets/svg/speed.svg +39 -39
- package/dist/components/BlocklyEditor.css +93 -93
- package/dist/components/JogPanel.css +41 -41
- package/dist/components/ProgressBarWithValue.css +27 -27
- package/dist/components/ValueIndicator.css +31 -31
- package/dist/components/osk.css +123 -123
- package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
- package/dist/core/AutoCoreTagContext.js +1 -1
- package/dist/hub/HubBase.d.ts +3 -3
- package/dist/hub/HubBase.d.ts.map +1 -1
- package/dist/hub/HubBase.js +1 -1
- package/package.json +104 -104
- package/readme.md +343 -343
- package/src/assets/BlocklyLogo.tsx +27 -27
- package/src/assets/Distance.tsx +18 -18
- package/src/assets/JogLong.tsx +13 -13
- package/src/assets/JogMedium.tsx +13 -13
- package/src/assets/JogShort.tsx +13 -13
- package/src/assets/PythonLogo.tsx +83 -83
- package/src/assets/Rotation3D.tsx +13 -13
- package/src/assets/RotationCcw.tsx +33 -33
- package/src/assets/RotationCcwA.tsx +45 -45
- package/src/assets/RotationCcwB.tsx +45 -45
- package/src/assets/RotationCcwC.tsx +45 -45
- package/src/assets/RotationCw.tsx +31 -31
- package/src/assets/RotationCwA.tsx +42 -42
- package/src/assets/RotationCwB.tsx +42 -42
- package/src/assets/RotationCwC.tsx +42 -42
- package/src/assets/Run.tsx +13 -13
- package/src/assets/Speed.tsx +18 -18
- package/src/assets/SpeedFast.tsx +13 -13
- package/src/assets/SpeedMedium.tsx +13 -13
- package/src/assets/SpeedNone.tsx +13 -13
- package/src/assets/SpeedSlow.tsx +13 -13
- package/src/assets/Walk.tsx +13 -13
- package/src/assets/index.ts +22 -22
- package/src/assets/svg/blockly_logo.svg +82 -82
- package/src/assets/svg/distance.svg +40 -40
- package/src/assets/svg/python_logo.svg +246 -246
- package/src/assets/svg/rotation_ccw.svg +50 -50
- package/src/assets/svg/rotation_ccw_a.svg +57 -57
- package/src/assets/svg/rotation_ccw_b.svg +57 -57
- package/src/assets/svg/rotation_ccw_c.svg +57 -57
- package/src/assets/svg/rotation_cw.svg +49 -49
- package/src/assets/svg/rotation_cw_a.svg +30 -30
- package/src/assets/svg/rotation_cw_b.svg +30 -30
- package/src/assets/svg/rotation_cw_c.svg +30 -30
- package/src/assets/svg/speed.svg +39 -39
- package/src/components/AutoCoreDevPanel.tsx +414 -414
- package/src/components/BlocklyEditor.css +93 -93
- package/src/components/BlocklyEditor.tsx +609 -609
- package/src/components/CodeEditor.tsx +155 -155
- package/src/components/FileList.tsx +390 -390
- package/src/components/FileSelect.tsx +128 -128
- package/src/components/FitText.tsx +35 -35
- package/src/components/Indicator.tsx +188 -188
- package/src/components/IndicatorButton.tsx +214 -214
- package/src/components/IndicatorRect.tsx +172 -172
- package/src/components/JogPanel.css +41 -41
- package/src/components/JogPanel.tsx +461 -461
- package/src/components/Lamp.tsx +243 -243
- package/src/components/Osk.tsx +192 -192
- package/src/components/OskDialog.tsx +164 -164
- package/src/components/ProgressBarWithValue.css +27 -27
- package/src/components/ProgressBarWithValue.tsx +48 -48
- package/src/components/TextInput.tsx +195 -195
- package/src/components/ToggleGroup.tsx +322 -322
- package/src/components/ValueDisplay.tsx +236 -236
- package/src/components/ValueIndicator.css +31 -31
- package/src/components/ValueIndicator.tsx +135 -135
- package/src/components/ValueInput.tsx +368 -368
- package/src/components/osk.css +123 -123
- package/src/core/ActionMode.ts +19 -19
- package/src/core/AutoCoreTagContext.tsx +625 -614
- package/src/core/AutoCoreTagTypes.ts +334 -334
- package/src/core/CoreStreamTypes.ts +512 -512
- package/src/core/EventEmitterContext.tsx +434 -434
- package/src/core/IndicatorButtonState.ts +34 -34
- package/src/core/IndicatorColor.ts +35 -35
- package/src/core/MaskPatterns.ts +87 -87
- package/src/core/NumerableTypes.ts +80 -80
- package/src/core/PositionContext.ts +59 -59
- package/src/core/UniqueId.ts +41 -41
- package/src/core/ValueSimulator.ts +166 -166
- package/src/core/hoc.tsx +65 -65
- package/src/hooks/adsHooks.tsx +287 -287
- package/src/hooks/commandHooks.tsx +300 -300
- package/src/hooks/index.ts +12 -12
- package/src/hooks/useAutoCoreTag.ts +103 -103
- package/src/hooks/useScaledValue.tsx +99 -99
- package/src/hub/CommandMessage.ts +89 -89
- package/src/hub/DebugPanel.ts +307 -307
- package/src/hub/HubBase.ts +249 -236
- package/src/hub/HubSimulate.ts +124 -124
- package/src/hub/HubTauri.ts +140 -140
- package/src/hub/HubWebSocket.ts +250 -250
- package/src/hub/debug.ts +211 -211
- package/src/hub/index.ts +81 -81
- package/src/themes/adc-dark/_extensions.scss +166 -166
- package/src/themes/adc-dark/_variables.scss +913 -913
- package/src/themes/adc-dark/blue/_fonts.scss +23 -23
- package/src/themes/adc-dark/blue/adc_theme.scss +31 -31
- package/src/themes/adc-dark/blue/theme.scss +14 -14
- package/src/themes/theme-base/_colors.scss +17 -17
- package/src/themes/theme-base/_common.scss +74 -74
- package/src/themes/theme-base/_components.scss +111 -111
- package/src/themes/theme-base/_mixins.scss +243 -243
- package/src/themes/theme-base/components/button/_button.scss +644 -644
- package/src/themes/theme-base/components/button/_speeddial.scss +91 -91
- package/src/themes/theme-base/components/button/_splitbutton.scss +358 -358
- package/src/themes/theme-base/components/data/_carousel.scss +39 -39
- package/src/themes/theme-base/components/data/_datascroller.scss +47 -47
- package/src/themes/theme-base/components/data/_datatable.scss +388 -388
- package/src/themes/theme-base/components/data/_dataview.scss +47 -47
- package/src/themes/theme-base/components/data/_filter.scss +137 -137
- package/src/themes/theme-base/components/data/_orderlist.scss +86 -86
- package/src/themes/theme-base/components/data/_organizationchart.scss +50 -50
- package/src/themes/theme-base/components/data/_paginator.scss +91 -91
- package/src/themes/theme-base/components/data/_picklist.scss +73 -73
- package/src/themes/theme-base/components/data/_timeline.scss +38 -38
- package/src/themes/theme-base/components/data/_tree.scss +184 -184
- package/src/themes/theme-base/components/data/_treetable.scss +431 -431
- package/src/themes/theme-base/components/file/_fileupload.scss +41 -41
- package/src/themes/theme-base/components/input/_autocomplete.scss +94 -94
- package/src/themes/theme-base/components/input/_calendar.scss +251 -251
- package/src/themes/theme-base/components/input/_cascadeselect.scss +107 -107
- package/src/themes/theme-base/components/input/_checkbox.scss +181 -181
- package/src/themes/theme-base/components/input/_chips.scss +102 -102
- package/src/themes/theme-base/components/input/_colorpicker.scss +17 -17
- package/src/themes/theme-base/components/input/_dropdown.scss +252 -252
- package/src/themes/theme-base/components/input/_editor.scss +122 -122
- package/src/themes/theme-base/components/input/_iconfield.scss +9 -9
- package/src/themes/theme-base/components/input/_inputgroup.scss +74 -74
- package/src/themes/theme-base/components/input/_inputicon.scss +14 -14
- package/src/themes/theme-base/components/input/_inputnumber.scss +4 -4
- package/src/themes/theme-base/components/input/_inputotp.scss +10 -10
- package/src/themes/theme-base/components/input/_inputswitch.scss +99 -99
- package/src/themes/theme-base/components/input/_inputtext.scss +101 -101
- package/src/themes/theme-base/components/input/_listbox.scss +138 -138
- package/src/themes/theme-base/components/input/_mention.scss +30 -30
- package/src/themes/theme-base/components/input/_multiselect.scss +278 -278
- package/src/themes/theme-base/components/input/_password.scss +32 -32
- package/src/themes/theme-base/components/input/_radiobutton.scss +169 -169
- package/src/themes/theme-base/components/input/_rating.scss +80 -80
- package/src/themes/theme-base/components/input/_selectbutton.scss +49 -49
- package/src/themes/theme-base/components/input/_slider.scss +49 -49
- package/src/themes/theme-base/components/input/_togglebutton.scss +99 -99
- package/src/themes/theme-base/components/input/_treeselect.scss +151 -151
- package/src/themes/theme-base/components/input/_tristatecheckbox.scss +46 -46
- package/src/themes/theme-base/components/menu/_breadcrumb.scss +42 -42
- package/src/themes/theme-base/components/menu/_contextmenu.scss +39 -39
- package/src/themes/theme-base/components/menu/_dock.scss +109 -109
- package/src/themes/theme-base/components/menu/_megamenu.scss +141 -141
- package/src/themes/theme-base/components/menu/_menu.scss +33 -33
- package/src/themes/theme-base/components/menu/_menubar.scss +216 -216
- package/src/themes/theme-base/components/menu/_panelmenu.scss +153 -153
- package/src/themes/theme-base/components/menu/_slidemenu.scss +60 -60
- package/src/themes/theme-base/components/menu/_steps.scss +57 -57
- package/src/themes/theme-base/components/menu/_tabmenu.scss +50 -50
- package/src/themes/theme-base/components/menu/_tieredmenu.scss +43 -43
- package/src/themes/theme-base/components/messages/_inlinemessage.scss +69 -69
- package/src/themes/theme-base/components/messages/_message.scss +107 -107
- package/src/themes/theme-base/components/messages/_toast.scss +100 -100
- package/src/themes/theme-base/components/misc/_avatar.scss +33 -33
- package/src/themes/theme-base/components/misc/_badge.scss +76 -76
- package/src/themes/theme-base/components/misc/_chip.scss +38 -38
- package/src/themes/theme-base/components/misc/_inplace.scss +17 -17
- package/src/themes/theme-base/components/misc/_metergroup.scss +80 -80
- package/src/themes/theme-base/components/misc/_progressbar.scss +17 -17
- package/src/themes/theme-base/components/misc/_scrolltop.scss +24 -24
- package/src/themes/theme-base/components/misc/_skeleton.scss +7 -7
- package/src/themes/theme-base/components/misc/_tag.scss +39 -39
- package/src/themes/theme-base/components/misc/_terminal.scss +12 -12
- package/src/themes/theme-base/components/multimedia/_galleria.scss +153 -153
- package/src/themes/theme-base/components/multimedia/_image.scss +53 -53
- package/src/themes/theme-base/components/overlay/_confirmpopup.scss +72 -72
- package/src/themes/theme-base/components/overlay/_dialog.scss +78 -78
- package/src/themes/theme-base/components/overlay/_overlaypanel.scss +64 -64
- package/src/themes/theme-base/components/overlay/_sidebar.scss +23 -23
- package/src/themes/theme-base/components/overlay/_tooltip.scss +33 -33
- package/src/themes/theme-base/components/panel/_accordion.scss +118 -118
- package/src/themes/theme-base/components/panel/_card.scss +30 -30
- package/src/themes/theme-base/components/panel/_divider.scss +30 -30
- package/src/themes/theme-base/components/panel/_fieldset.scss +47 -47
- package/src/themes/theme-base/components/panel/_panel.scss +47 -47
- package/src/themes/theme-base/components/panel/_scrollpanel.scss +10 -10
- package/src/themes/theme-base/components/panel/_splitter.scss +23 -23
- package/src/themes/theme-base/components/panel/_stepper.scss +136 -136
- package/src/themes/theme-base/components/panel/_tabview.scss +147 -147
- package/src/themes/theme-base/components/panel/_toolbar.scss +11 -11
- package/terser.config.cjs +25 -25
- package/todo.md +18 -18
- package/tools/build-themes.cjs +65 -65
- package/tools/copy-distribution-files.cjs +77 -77
- package/tools/minify.cjs +55 -55
- package/tsconfig.json +48 -48
- package/typedoc.json +12 -12
- 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
|
+
}
|