@wandelbots/wandelbots-js-react-components 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -16
- package/dist/components/3d-viewport/SafetyZonesRenderer.d.ts +1 -1
- package/dist/components/3d-viewport/SafetyZonesRenderer.d.ts.map +1 -1
- package/dist/components/CopyableText.d.ts +5 -0
- package/dist/components/CopyableText.d.ts.map +1 -0
- package/dist/components/LoadingButton.d.ts +1 -1
- package/dist/components/LoadingButton.stories.d.ts +1 -1
- package/dist/components/LoadingButton.stories.d.ts.map +1 -1
- package/dist/components/ThemeSelect.d.ts.map +1 -1
- package/dist/components/VelocitySlider.d.ts.map +1 -1
- package/dist/components/VelocitySlider.stories.d.ts +2 -2
- package/dist/components/VelocitySlider.stories.d.ts.map +1 -1
- package/dist/components/jogging/JoggingCartesianAxisControl.stories.d.ts +1 -1
- package/dist/components/jogging/JoggingCartesianAxisControl.stories.d.ts.map +1 -1
- package/dist/components/jogging/JoggingCartesianTab.d.ts.map +1 -1
- package/dist/components/jogging/JoggingCartesianValues.d.ts +1 -1
- package/dist/components/jogging/JoggingCartesianValues.d.ts.map +1 -1
- package/dist/components/jogging/JoggingJointLimitDetector.d.ts +2 -2
- package/dist/components/jogging/JoggingJointLimitDetector.d.ts.map +1 -1
- package/dist/components/jogging/JoggingJointRotationControl.d.ts.map +1 -1
- package/dist/components/jogging/JoggingJointRotationControl.stories.d.ts +2 -2
- package/dist/components/jogging/JoggingJointRotationControl.stories.d.ts.map +1 -1
- package/dist/components/jogging/JoggingJointValues.d.ts +1 -1
- package/dist/components/jogging/JoggingJointValues.d.ts.map +1 -1
- package/dist/components/jogging/JoggingOptions.d.ts.map +1 -1
- package/dist/components/jogging/JoggingPanel.d.ts +8 -1
- package/dist/components/jogging/JoggingPanel.d.ts.map +1 -1
- package/dist/components/jogging/JoggingPanel.stories.d.ts +2 -2
- package/dist/components/jogging/JoggingPanel.stories.d.ts.map +1 -1
- package/dist/components/jogging/JoggingStore.d.ts +14 -1
- package/dist/components/jogging/JoggingStore.d.ts.map +1 -1
- package/dist/components/jogging/JoggingVelocitySlider.d.ts.map +1 -1
- package/dist/components/wandelscript-editor/WandelscriptEditor.d.ts +2 -2
- package/dist/components/wandelscript-editor/WandelscriptEditor.d.ts.map +1 -1
- package/dist/components/wandelscript-editor/WandelscriptEditor.stories.d.ts +2 -2
- package/dist/components/wandelscript-editor/WandelscriptEditor.stories.d.ts.map +1 -1
- package/dist/externalizeComponent.d.ts +7 -0
- package/dist/externalizeComponent.d.ts.map +1 -0
- package/dist/index.cjs +29 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +49 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11681 -12331
- package/dist/index.js.map +1 -1
- package/dist/themes/color.d.ts +1 -1
- package/dist/themes/color.d.ts.map +1 -1
- package/dist/themes/novaTheme.stories.d.ts +5 -0
- package/dist/themes/novaTheme.stories.d.ts.map +1 -0
- package/dist/themes/theming.d.ts +49 -0
- package/dist/themes/theming.d.ts.map +1 -0
- package/package.json +20 -13
- package/src/components/3d-viewport/SafetyZonesRenderer.tsx +2 -2
- package/src/components/CopyableText.tsx +30 -0
- package/src/components/LoadingButton.stories.tsx +19 -26
- package/src/components/ThemeSelect.tsx +3 -4
- package/src/components/VelocitySlider.stories.tsx +10 -15
- package/src/components/VelocitySlider.tsx +7 -2
- package/src/components/jogging/JoggingCartesianAxisControl.stories.tsx +21 -21
- package/src/components/jogging/JoggingCartesianAxisControl.tsx +1 -1
- package/src/components/jogging/JoggingCartesianTab.tsx +37 -44
- package/src/components/jogging/JoggingCartesianValues.tsx +37 -33
- package/src/components/jogging/JoggingJointLimitDetector.tsx +10 -7
- package/src/components/jogging/JoggingJointRotationControl.stories.tsx +31 -19
- package/src/components/jogging/JoggingJointRotationControl.tsx +44 -30
- package/src/components/jogging/JoggingJointValues.tsx +35 -33
- package/src/components/jogging/JoggingOptions.tsx +130 -80
- package/src/components/jogging/JoggingPanel.stories.tsx +20 -17
- package/src/components/jogging/JoggingPanel.tsx +29 -31
- package/src/components/jogging/JoggingStore.tsx +69 -18
- package/src/components/jogging/JoggingVelocitySlider.tsx +24 -22
- package/src/components/wandelscript-editor/WandelscriptEditor.stories.tsx +7 -7
- package/src/components/wandelscript-editor/WandelscriptEditor.tsx +48 -23
- package/src/externalizeComponent.tsx +37 -0
- package/src/i18n/locales/de/translations.json +2 -1
- package/src/i18n/locales/en/translations.json +2 -1
- package/src/icons/orientation-coord-system.svg +3 -0
- package/src/icons/orientation-tool.svg +3 -0
- package/src/index.ts +39 -9
- package/src/themes/color.tsx +29 -19
- package/src/themes/novaTheme.stories.tsx +77 -0
- package/src/themes/themeTypes.d.ts +11 -0
- package/src/themes/theming.ts +174 -0
- package/dist/themes/theme.d.ts +0 -144
- package/dist/themes/theme.d.ts.map +0 -1
- package/dist/themes/wbTheme.d.ts +0 -73
- package/dist/themes/wbTheme.d.ts.map +0 -1
- package/dist/themes/wbTheme.stories.d.ts +0 -7
- package/dist/themes/wbTheme.stories.d.ts.map +0 -1
- package/src/themes/theme.ts +0 -150
- package/src/themes/wbTheme.stories.tsx +0 -64
- package/src/themes/wbTheme.ts +0 -186
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
import { Meta, StoryObj } from "@storybook/react"
|
|
2
|
-
import { JoggingPanel } from "
|
|
3
|
-
import { useArgs } from "@storybook/preview-api"
|
|
4
|
-
import { NovaClient } from "@wandelbots/wandelbots-js"
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { JoggingPanel } from "../../index"
|
|
3
|
+
import { useArgs } from "@storybook/preview-api"
|
|
4
|
+
import { NovaClient } from "@wandelbots/wandelbots-js"
|
|
5
5
|
|
|
6
6
|
const meta: Meta<typeof JoggingPanel> = {
|
|
7
7
|
component: JoggingPanel,
|
|
8
8
|
|
|
9
9
|
args: {
|
|
10
|
-
motionGroupId: "0@mock-ur5e"
|
|
10
|
+
motionGroupId: "0@mock-ur5e",
|
|
11
11
|
},
|
|
12
12
|
render: function Component(args) {
|
|
13
|
-
const [, setArgs] = useArgs()
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const [, setArgs] = useArgs()
|
|
14
|
+
return (
|
|
15
|
+
<JoggingPanel
|
|
16
|
+
{...args}
|
|
17
|
+
nova={
|
|
18
|
+
new NovaClient({
|
|
19
|
+
instanceUrl: "https://mock",
|
|
20
|
+
mock: true,
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
/>
|
|
24
|
+
)
|
|
21
25
|
},
|
|
22
|
-
}
|
|
23
|
-
export default meta
|
|
26
|
+
}
|
|
27
|
+
export default meta
|
|
24
28
|
|
|
25
|
-
export const Default: StoryObj<typeof JoggingPanel> = {
|
|
26
|
-
};
|
|
29
|
+
export const Default: StoryObj<typeof JoggingPanel> = {}
|
|
@@ -6,11 +6,17 @@ import { JoggingJointTab } from "./JoggingJointTab"
|
|
|
6
6
|
import { JoggingStore } from "./JoggingStore"
|
|
7
7
|
import { LoadingCover } from "../LoadingCover"
|
|
8
8
|
import { runInAction } from "mobx"
|
|
9
|
-
import { NovaClient } from "@wandelbots/wandelbots-js"
|
|
9
|
+
import type { NovaClient } from "@wandelbots/wandelbots-js"
|
|
10
10
|
|
|
11
11
|
export type JoggingPanelProps = {
|
|
12
|
+
/** Connection to a Nova instance to use for jogging */
|
|
12
13
|
nova: NovaClient
|
|
14
|
+
/** Id of the motion group to move e.g. 0@ur5e **/
|
|
13
15
|
motionGroupId: string
|
|
16
|
+
/** Callback with the jogging panel's state store for further customization/config */
|
|
17
|
+
onSetup?: (store: JoggingStore) => void
|
|
18
|
+
/** Any children will go at the bottom of the panel under the default components */
|
|
19
|
+
children?: React.ReactNode
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
export const JoggingPanel = observer((props: JoggingPanelProps) => {
|
|
@@ -28,6 +34,9 @@ export const JoggingPanel = observer((props: JoggingPanelProps) => {
|
|
|
28
34
|
runInAction(() => {
|
|
29
35
|
state.joggingStore = joggingStore
|
|
30
36
|
})
|
|
37
|
+
if (props.onSetup) {
|
|
38
|
+
props.onSetup(joggingStore)
|
|
39
|
+
}
|
|
31
40
|
} catch (err) {
|
|
32
41
|
state.loadingError = err
|
|
33
42
|
}
|
|
@@ -47,7 +56,7 @@ export const JoggingPanel = observer((props: JoggingPanelProps) => {
|
|
|
47
56
|
const {
|
|
48
57
|
currentTab,
|
|
49
58
|
selectedTcpId,
|
|
50
|
-
|
|
59
|
+
activeCoordSystemId,
|
|
51
60
|
selectedDiscreteIncrement,
|
|
52
61
|
} = state.joggingStore
|
|
53
62
|
|
|
@@ -55,40 +64,27 @@ export const JoggingPanel = observer((props: JoggingPanelProps) => {
|
|
|
55
64
|
|
|
56
65
|
const cartesianJoggingOpts = {
|
|
57
66
|
tcpId: selectedTcpId,
|
|
58
|
-
coordSystemId:
|
|
67
|
+
coordSystemId: activeCoordSystemId,
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
if (selectedDiscreteIncrement && currentTab.id === "cartesian") {
|
|
62
|
-
state.joggingStore.jogger.setJoggingMode(
|
|
71
|
+
state.joggingStore.jogger.setJoggingMode(
|
|
72
|
+
"increment",
|
|
73
|
+
cartesianJoggingOpts,
|
|
74
|
+
)
|
|
63
75
|
} else {
|
|
64
|
-
state.joggingStore.jogger.setJoggingMode(
|
|
76
|
+
state.joggingStore.jogger.setJoggingMode(
|
|
77
|
+
currentTab.id,
|
|
78
|
+
cartesianJoggingOpts,
|
|
79
|
+
)
|
|
65
80
|
}
|
|
66
81
|
}, [
|
|
67
82
|
state.joggingStore?.currentTab,
|
|
68
83
|
state.joggingStore?.selectedTcpId,
|
|
69
|
-
state.joggingStore?.
|
|
84
|
+
state.joggingStore?.activeCoordSystemId,
|
|
70
85
|
state.joggingStore?.selectedDiscreteIncrement,
|
|
71
86
|
])
|
|
72
87
|
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
|
|
75
|
-
// Set the robot to default control mode (JoZi says is important for physical robot jogging)
|
|
76
|
-
async function init() {
|
|
77
|
-
if (!state.joggingStore) return
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
await nova.api.controller.setDefaultMode(
|
|
81
|
-
state.joggingStore.jogger.motionStream.controllerId,
|
|
82
|
-
"MODE_CONTROL",
|
|
83
|
-
)
|
|
84
|
-
} catch (err) {
|
|
85
|
-
console.error(err)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
init()
|
|
90
|
-
}, [state.joggingStore?.jogger.motionStream.controllerId])
|
|
91
|
-
|
|
92
88
|
if (!state.joggingStore) {
|
|
93
89
|
return (
|
|
94
90
|
<JoggingPanelOuter>
|
|
@@ -119,9 +115,8 @@ export const JoggingPanel = observer((props: JoggingPanelProps) => {
|
|
|
119
115
|
{store.currentTab.id === "cartesian" && (
|
|
120
116
|
<JoggingCartesianTab store={store} />
|
|
121
117
|
)}
|
|
122
|
-
{store.currentTab.id === "joint" &&
|
|
123
|
-
|
|
124
|
-
)}
|
|
118
|
+
{store.currentTab.id === "joint" && <JoggingJointTab store={store} />}
|
|
119
|
+
{props.children}
|
|
125
120
|
</Stack>
|
|
126
121
|
</Stack>
|
|
127
122
|
</JoggingPanelOuter>
|
|
@@ -136,11 +131,14 @@ function JoggingPanelOuter({ children }: { children: React.ReactNode }) {
|
|
|
136
131
|
minWidth: "350px",
|
|
137
132
|
overflowY: "auto",
|
|
138
133
|
position: "relative",
|
|
134
|
+
height: "100%",
|
|
139
135
|
}}
|
|
140
136
|
>
|
|
141
|
-
<Paper
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
<Paper
|
|
138
|
+
sx={{
|
|
139
|
+
height: "100%",
|
|
140
|
+
}}
|
|
141
|
+
>
|
|
144
142
|
{children}
|
|
145
143
|
</Paper>
|
|
146
144
|
</Stack>
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { keyBy } from "lodash-es"
|
|
1
|
+
import { keyBy, uniqueId } from "lodash-es"
|
|
2
2
|
import { autorun, makeAutoObservable, type IReactionDisposer } from "mobx"
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
CoordinateSystem,
|
|
5
|
+
JoggerConnection,
|
|
6
|
+
MotionGroupSpecification,
|
|
7
|
+
RobotTcp,
|
|
8
|
+
} from "@wandelbots/wandelbots-js"
|
|
4
9
|
import { tryParseJson } from "@wandelbots/wandelbots-js"
|
|
5
10
|
|
|
6
11
|
const discreteIncrementOptions = [
|
|
@@ -22,8 +27,8 @@ export type IncrementOptionId = IncrementOption["id"]
|
|
|
22
27
|
export class JoggingStore {
|
|
23
28
|
selectedTabId: "cartesian" | "joint" | "debug" = "cartesian"
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
/** Locks to prevent UI interactions during certain operations */
|
|
31
|
+
locks = new Set<string>()
|
|
27
32
|
|
|
28
33
|
/**
|
|
29
34
|
* Id of selected coordinate system from among those defined on the API side
|
|
@@ -33,6 +38,13 @@ export class JoggingStore {
|
|
|
33
38
|
/** Id of selected tool center point from among the options available on the robot */
|
|
34
39
|
selectedTcpId: string = ""
|
|
35
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Whether the user is jogging in the coordinate system or tool orientation.
|
|
43
|
+
* When in tool orientation, the robot moves in a direction relative to the
|
|
44
|
+
* attached tool rotation.
|
|
45
|
+
*/
|
|
46
|
+
selectedOrientation: "coordsys" | "tool" = "coordsys"
|
|
47
|
+
|
|
36
48
|
/**
|
|
37
49
|
* Id of selected increment amount for jogging. Options are defined by robot pad.
|
|
38
50
|
* When non-continuous, jogging moves the robot by a fixed number of mm or degrees
|
|
@@ -74,20 +86,28 @@ export class JoggingStore {
|
|
|
74
86
|
const { nova } = jogger
|
|
75
87
|
|
|
76
88
|
// Find out what TCPs this motion group has (we need it for jogging)
|
|
77
|
-
const [motionGroupSpec, { coordinatesystems }, { tcps }] =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
const [motionGroupSpec, { coordinatesystems }, { tcps }] =
|
|
90
|
+
await Promise.all([
|
|
91
|
+
nova.api.motionGroupInfos.getMotionGroupSpecification(
|
|
92
|
+
jogger.motionGroupId,
|
|
93
|
+
),
|
|
94
|
+
|
|
95
|
+
// Fetch coord systems so user can select between them
|
|
96
|
+
nova.api.coordinateSystems.listCoordinateSystems("ROTATION_VECTOR"),
|
|
97
|
+
|
|
98
|
+
// Same for TCPs
|
|
99
|
+
nova.api.motionGroupInfos.listTcps(
|
|
100
|
+
jogger.motionGroupId,
|
|
101
|
+
"ROTATION_VECTOR",
|
|
102
|
+
),
|
|
103
|
+
])
|
|
104
|
+
|
|
105
|
+
return new JoggingStore(
|
|
106
|
+
jogger,
|
|
107
|
+
motionGroupSpec,
|
|
108
|
+
coordinatesystems || [],
|
|
109
|
+
tcps || [],
|
|
110
|
+
)
|
|
91
111
|
}
|
|
92
112
|
|
|
93
113
|
constructor(
|
|
@@ -147,6 +167,10 @@ export class JoggingStore {
|
|
|
147
167
|
if (["translate", "rotate"].includes(save.selectedCartesianMotionType)) {
|
|
148
168
|
this.selectedCartesianMotionType = save.selectedCartesianMotionType
|
|
149
169
|
}
|
|
170
|
+
|
|
171
|
+
if (["coordsys", "tool"].includes(save.selectedOrientation)) {
|
|
172
|
+
this.selectedOrientation = save.selectedOrientation
|
|
173
|
+
}
|
|
150
174
|
}
|
|
151
175
|
|
|
152
176
|
saveToLocalStorage() {
|
|
@@ -156,11 +180,16 @@ export class JoggingStore {
|
|
|
156
180
|
)
|
|
157
181
|
}
|
|
158
182
|
|
|
183
|
+
get isLocked() {
|
|
184
|
+
return this.locks.size > 0
|
|
185
|
+
}
|
|
186
|
+
|
|
159
187
|
get localStorageSave() {
|
|
160
188
|
return {
|
|
161
189
|
selectedTabId: this.selectedTabId,
|
|
162
190
|
selectedCoordSystemId: this.selectedCoordSystemId,
|
|
163
191
|
selectedTcpId: this.selectedTcpId,
|
|
192
|
+
selectedOrientation: this.selectedOrientation,
|
|
164
193
|
selectedIncrementId: this.selectedIncrementId,
|
|
165
194
|
selectedCartesianMotionType: this.selectedCartesianMotionType,
|
|
166
195
|
}
|
|
@@ -211,6 +240,12 @@ export class JoggingStore {
|
|
|
211
240
|
return this.coordSystemsById[this.selectedCoordSystemId]
|
|
212
241
|
}
|
|
213
242
|
|
|
243
|
+
get activeCoordSystemId() {
|
|
244
|
+
return this.selectedOrientation === "tool"
|
|
245
|
+
? "tool"
|
|
246
|
+
: this.selectedCoordSystemId
|
|
247
|
+
}
|
|
248
|
+
|
|
214
249
|
get tcpsById() {
|
|
215
250
|
return keyBy(this.tcps, (tcp) => tcp.id)
|
|
216
251
|
}
|
|
@@ -272,6 +307,10 @@ export class JoggingStore {
|
|
|
272
307
|
this.selectedTcpId = id
|
|
273
308
|
}
|
|
274
309
|
|
|
310
|
+
setSelectedOrientation(orientation: "coordsys" | "tool") {
|
|
311
|
+
this.selectedOrientation = orientation
|
|
312
|
+
}
|
|
313
|
+
|
|
275
314
|
setSelectedIncrementId(id: IncrementOptionId) {
|
|
276
315
|
this.selectedIncrementId = id
|
|
277
316
|
}
|
|
@@ -291,4 +330,16 @@ export class JoggingStore {
|
|
|
291
330
|
setSelectedCartesianMotionType(type: "translate" | "rotate") {
|
|
292
331
|
this.selectedCartesianMotionType = type
|
|
293
332
|
}
|
|
333
|
+
|
|
334
|
+
/** Lock the UI until the given async callback resolves */
|
|
335
|
+
async withMotionLock(fn: () => Promise<void>) {
|
|
336
|
+
const lockId = uniqueId()
|
|
337
|
+
this.locks.add(lockId)
|
|
338
|
+
|
|
339
|
+
try {
|
|
340
|
+
return await fn()
|
|
341
|
+
} finally {
|
|
342
|
+
this.locks.delete(lockId)
|
|
343
|
+
}
|
|
344
|
+
}
|
|
294
345
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Stack,
|
|
1
|
+
import { Stack, Typography } from "@mui/material"
|
|
2
2
|
import { observer, useLocalObservable } from "mobx-react-lite"
|
|
3
3
|
import type { JoggingStore } from "./JoggingStore"
|
|
4
4
|
import { VelocitySlider } from "../VelocitySlider"
|
|
@@ -21,35 +21,37 @@ export const JoggingVelocitySlider = observer(
|
|
|
21
21
|
}))
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
<Stack
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
<Stack
|
|
25
|
+
sx={{
|
|
26
|
+
margin: "0px 20px",
|
|
27
|
+
marginTop: "24px",
|
|
28
|
+
marginBottom: "24px",
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<Stack sx={{ width: "380px", maxWidth: "90%", margin: "auto" }}>
|
|
32
|
+
<Stack
|
|
33
|
+
sx={{
|
|
34
|
+
justifyContent: "center",
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
34
37
|
<Typography
|
|
35
38
|
sx={{
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
fontSize: "12px",
|
|
40
|
+
opacity: 0.6,
|
|
38
41
|
}}
|
|
39
42
|
>
|
|
40
43
|
{t("Jogging.Velocity.lb")}
|
|
41
44
|
</Typography>
|
|
42
|
-
<VelocitySlider
|
|
43
|
-
velocity={store.velocityInCurrentUnits}
|
|
44
|
-
min={store.minVelocityInCurrentUnits}
|
|
45
|
-
max={store.maxVelocityInCurrentUnits}
|
|
46
|
-
onVelocityChange={store.setVelocityFromSlider}
|
|
47
|
-
disabled={store.isLocked}
|
|
48
|
-
valueLabelFormat={state.valueLabelFormat}
|
|
49
|
-
/>
|
|
50
45
|
</Stack>
|
|
46
|
+
<VelocitySlider
|
|
47
|
+
velocity={store.velocityInCurrentUnits}
|
|
48
|
+
min={store.minVelocityInCurrentUnits}
|
|
49
|
+
max={store.maxVelocityInCurrentUnits}
|
|
50
|
+
onVelocityChange={store.setVelocityFromSlider}
|
|
51
|
+
disabled={store.isLocked}
|
|
52
|
+
valueLabelFormat={state.valueLabelFormat}
|
|
53
|
+
/>
|
|
51
54
|
</Stack>
|
|
52
|
-
<Divider />
|
|
53
55
|
</Stack>
|
|
54
56
|
)
|
|
55
57
|
},
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Meta, StoryObj } from "@storybook/react"
|
|
2
|
-
import { WandelscriptEditor } from "
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { WandelscriptEditor } from "../../index"
|
|
3
3
|
|
|
4
4
|
const meta: Meta<typeof WandelscriptEditor> = {
|
|
5
5
|
component: WandelscriptEditor,
|
|
6
|
-
}
|
|
7
|
-
export default meta
|
|
6
|
+
}
|
|
7
|
+
export default meta
|
|
8
8
|
|
|
9
9
|
const defaultCode = `start = [832, -452, 289] # The start position of the edge
|
|
10
10
|
end = [817, 168, 288] # The end position of the edge
|
|
@@ -29,7 +29,7 @@ for i = 0..<int(n / 2) - 1:
|
|
|
29
29
|
move via arc(a) to b
|
|
30
30
|
if i == 10:
|
|
31
31
|
test_pose = planned_pose()
|
|
32
|
-
|
|
32
|
+
`
|
|
33
33
|
|
|
34
34
|
export const Editor: StoryObj<typeof WandelscriptEditor> = {
|
|
35
35
|
args: {
|
|
@@ -40,6 +40,6 @@ export const Editor: StoryObj<typeof WandelscriptEditor> = {
|
|
|
40
40
|
<div style={{ height: "400px" }}>
|
|
41
41
|
<WandelscriptEditor {...props} />
|
|
42
42
|
</div>
|
|
43
|
-
)
|
|
43
|
+
)
|
|
44
44
|
},
|
|
45
|
-
}
|
|
45
|
+
}
|
|
@@ -1,29 +1,46 @@
|
|
|
1
1
|
import Editor, { useMonaco, type Monaco } from "@monaco-editor/react"
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { useEffect, useRef, useState } from "react"
|
|
3
|
+
import type {
|
|
4
|
+
BundledLanguage,
|
|
5
|
+
HighlighterGeneric} from "shiki";
|
|
6
|
+
import {
|
|
7
|
+
createHighlighter,
|
|
8
|
+
type BundledTheme,
|
|
9
|
+
} from "shiki"
|
|
4
10
|
import { shikiToMonaco } from "@shikijs/monaco"
|
|
5
11
|
|
|
6
12
|
import wandelscriptTextmateGrammar from "./wandelscript.tmLanguage"
|
|
7
13
|
import { useTheme } from "@mui/material"
|
|
8
|
-
import { editor } from "monaco-editor"
|
|
14
|
+
import type { editor } from "monaco-editor"
|
|
9
15
|
|
|
10
16
|
type WandelscriptEditorProps = {
|
|
11
17
|
/** The current Wandelscript content of the code editor (controlled component) */
|
|
12
18
|
code?: string
|
|
13
19
|
/** What to do when the user edits the code */
|
|
14
|
-
onChange?: (
|
|
15
|
-
|
|
20
|
+
onChange?: (
|
|
21
|
+
code: string | undefined,
|
|
22
|
+
ev: editor.IModelContentChangedEvent,
|
|
23
|
+
) => void
|
|
24
|
+
/** Options for monaco editor */
|
|
16
25
|
monacoOptions?: editor.IEditorOptions
|
|
17
26
|
/** Callback to further configure monaco on startup if needed */
|
|
18
27
|
monacoSetup?: (monaco: Monaco) => void
|
|
19
28
|
}
|
|
20
29
|
|
|
21
|
-
const shikiTheme: BundledTheme = "dark-plus"
|
|
22
|
-
|
|
23
30
|
/** A Monaco (VSCode-style) embedded code editor with Wandelscript syntax highlighting */
|
|
24
31
|
export const WandelscriptEditor = (props: WandelscriptEditorProps) => {
|
|
25
32
|
const monaco = useMonaco()
|
|
26
33
|
const theme = useTheme()
|
|
34
|
+
const shikiHighlighterRef = useRef<HighlighterGeneric<
|
|
35
|
+
BundledLanguage,
|
|
36
|
+
BundledTheme
|
|
37
|
+
> | null>(null)
|
|
38
|
+
|
|
39
|
+
const [activeShikiTheme, setActiveShikiTheme] =
|
|
40
|
+
useState<BundledTheme>("dark-plus")
|
|
41
|
+
|
|
42
|
+
const targetShikiTheme =
|
|
43
|
+
theme.palette.mode === "dark" ? "dark-plus" : "light-plus"
|
|
27
44
|
|
|
28
45
|
async function setupEditor(monaco: Monaco) {
|
|
29
46
|
// Register and configure the Wandelscript language
|
|
@@ -50,38 +67,46 @@ export const WandelscriptEditor = (props: WandelscriptEditorProps) => {
|
|
|
50
67
|
// Monaco doesn't support TextMate grammar config directly, so we
|
|
51
68
|
// use Shiki as an intermediary
|
|
52
69
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
if (!shikiHighlighterRef.current) {
|
|
71
|
+
shikiHighlighterRef.current = await createHighlighter({
|
|
72
|
+
// Our textmate grammar doesn't quite conform to the expected type
|
|
73
|
+
// here; I'm not sure what the missing properties mean exactly
|
|
74
|
+
langs: [wandelscriptTextmateGrammar as any],
|
|
75
|
+
themes: ["dark-plus", "light-plus"],
|
|
76
|
+
})
|
|
77
|
+
}
|
|
59
78
|
|
|
60
|
-
shikiToMonaco(
|
|
79
|
+
shikiToMonaco(shikiHighlighterRef.current, monaco)
|
|
61
80
|
|
|
62
81
|
// Override the generated shiki theme to use shiki syntax highlighting
|
|
63
82
|
// but vscode colors
|
|
64
|
-
monaco.editor.defineTheme(
|
|
83
|
+
monaco.editor.defineTheme(targetShikiTheme, {
|
|
65
84
|
base: theme.palette.mode === "dark" ? "vs-dark" : "vs",
|
|
66
85
|
inherit: true,
|
|
67
86
|
rules: [],
|
|
68
|
-
colors:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
87
|
+
colors:
|
|
88
|
+
theme.palette.mode === "dark"
|
|
89
|
+
? {
|
|
90
|
+
"editor.background": "#262F42",
|
|
91
|
+
"editorLineNumber.foreground": "#797979",
|
|
92
|
+
"editorLineNumber.activeForeground": "#e9e9e9",
|
|
93
|
+
"editor.lineHighlightBorder": "#494949",
|
|
94
|
+
}
|
|
95
|
+
: {},
|
|
73
96
|
})
|
|
74
97
|
|
|
75
98
|
if (props.monacoSetup) {
|
|
76
99
|
props.monacoSetup(monaco)
|
|
77
100
|
}
|
|
101
|
+
|
|
102
|
+
setActiveShikiTheme(targetShikiTheme)
|
|
78
103
|
}
|
|
79
104
|
|
|
80
105
|
useEffect(() => {
|
|
81
106
|
if (monaco) {
|
|
82
107
|
setupEditor(monaco)
|
|
83
108
|
}
|
|
84
|
-
}, [monaco])
|
|
109
|
+
}, [monaco, targetShikiTheme])
|
|
85
110
|
|
|
86
111
|
if (!monaco) {
|
|
87
112
|
return null
|
|
@@ -92,7 +117,7 @@ export const WandelscriptEditor = (props: WandelscriptEditorProps) => {
|
|
|
92
117
|
value={props.code}
|
|
93
118
|
onChange={props.onChange}
|
|
94
119
|
defaultLanguage="wandelscript"
|
|
95
|
-
theme={
|
|
120
|
+
theme={activeShikiTheme}
|
|
96
121
|
options={{
|
|
97
122
|
minimap: { enabled: false },
|
|
98
123
|
wordWrap: "on",
|
|
@@ -101,4 +126,4 @@ export const WandelscriptEditor = (props: WandelscriptEditorProps) => {
|
|
|
101
126
|
}}
|
|
102
127
|
/>
|
|
103
128
|
)
|
|
104
|
-
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ThemeProvider } from "@emotion/react"
|
|
2
|
+
import { createMUIThemeFromNova, createNovaTheme } from "./themes/theming"
|
|
3
|
+
import type { FC } from "react"
|
|
4
|
+
import { useTheme } from "@mui/material"
|
|
5
|
+
import { I18nextProvider } from "react-i18next"
|
|
6
|
+
// @ts-expect-error invalid type-only import error
|
|
7
|
+
import i18n from "./i18n/config"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Our components require a certain context that may or may not
|
|
11
|
+
* be provided by the user application; this wrapper ensures
|
|
12
|
+
* they can be used either way.
|
|
13
|
+
*/
|
|
14
|
+
export function externalizeComponent<T>(
|
|
15
|
+
Component: (props: T) => React.ReactNode,
|
|
16
|
+
) {
|
|
17
|
+
return (props: T) => (
|
|
18
|
+
<NovaComponentsProvider>
|
|
19
|
+
<Component {...(props as T & JSX.IntrinsicAttributes)} />
|
|
20
|
+
</NovaComponentsProvider>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const NovaComponentsProvider: FC<{ children: React.ReactNode }> = ({
|
|
25
|
+
children,
|
|
26
|
+
}) => {
|
|
27
|
+
const theme = useTheme()
|
|
28
|
+
const defaultNovaTheme = createNovaTheme({
|
|
29
|
+
mode: theme.palette.mode,
|
|
30
|
+
})
|
|
31
|
+
const defaultTheme = createMUIThemeFromNova(defaultNovaTheme)
|
|
32
|
+
return (
|
|
33
|
+
<ThemeProvider theme={defaultTheme}>
|
|
34
|
+
<I18nextProvider i18n={i18n}>{children}</I18nextProvider>
|
|
35
|
+
</ThemeProvider>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
@@ -8,5 +8,6 @@
|
|
|
8
8
|
"Jogging.Cartesian.Translation.bt": "Translation",
|
|
9
9
|
"Jogging.Cartesian.Rotation.bt": "Rotation",
|
|
10
10
|
"Jogging.Joints.JointValues.lb": "Gelenkwerte",
|
|
11
|
-
"Jogging.Increment.Continuous.dd": "Fortlaufend"
|
|
11
|
+
"Jogging.Increment.Continuous.dd": "Fortlaufend",
|
|
12
|
+
"Jogging.Cartesian.Orientation.lb": "Orientierung"
|
|
12
13
|
}
|
|
@@ -8,5 +8,6 @@
|
|
|
8
8
|
"Jogging.Cartesian.Translation.bt": "Translation",
|
|
9
9
|
"Jogging.Cartesian.Rotation.bt": "Rotation",
|
|
10
10
|
"Jogging.Joints.JointValues.lb": "Joint values",
|
|
11
|
-
"Jogging.Increment.Continuous.dd": "Continuous"
|
|
11
|
+
"Jogging.Increment.Continuous.dd": "Continuous",
|
|
12
|
+
"Jogging.Cartesian.Orientation.lb": "Orientation"
|
|
12
13
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="21" height="21" viewBox="0 0 23 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M21.7099 16.2621L20.6205 16.608L21.2793 18.679L18.3573 17.2179V9.85689L12.0715 6.71409V2.89269L13.3795 4.21073L14.1921 3.40503L11.5179 0.714233L8.81153 3.40223L9.61723 4.21363L10.9286 2.91113V6.71413L4.64295 9.85693V17.2179L1.72915 18.6747L2.38625 16.6083L1.29687 16.2625L0.0714111 20.1429L3.89721 21.2858L4.24307 20.1966L2.40729 19.6134L5.28149 18.1766L11.5001 21.2856L17.7183 18.1764L20.5947 19.6146L18.7635 20.1964L19.1094 21.2856L22.9286 20.1427L21.7099 16.2621ZM11.5001 12.6463L6.55967 10.1763L11.5001 7.70633L16.4409 10.1767L11.5001 12.6463ZM12.0715 13.6388L17.2145 11.0672V17.1504L12.0715 19.722V13.6388ZM5.78567 11.0672L10.9287 13.6388V19.722L5.78567 17.1504V11.0672Z" fill="currentColor"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M11.87 7.12001L13.56 8.81002L16.55 5.82001L12.82 2.09001L11.87 1.14001L4.21001 8.80001L3.26001 9.75001L7.25001 13.74V17.18H14.8V13.63L10.08 8.91001L11.87 7.12001ZM10.96 4.13001L11.87 3.22001L14.47 5.82001L13.56 6.73001L10.96 4.13001ZM8.71001 14.37H12.45L11.11 13.03L11.07 12.99H8.57001L5.32001 9.74001L9.91001 5.15001L10.83 6.07001L8.00001 8.90001L13.33 14.23V15.71H8.70001V14.36L8.71001 14.37Z" fill="currentColor" fill-opacity="0.8"/>
|
|
3
|
+
</svg>
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export * from "./components/
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
export * from "./components/
|
|
8
|
-
|
|
9
|
-
export
|
|
1
|
+
import { externalizeComponent } from "./externalizeComponent"
|
|
2
|
+
|
|
3
|
+
export type * from "./components/wandelscript-editor/WandelscriptEditor"
|
|
4
|
+
import { WandelscriptEditor as WE } from "./components/wandelscript-editor/WandelscriptEditor"
|
|
5
|
+
export const WandelscriptEditor = externalizeComponent(WE)
|
|
6
|
+
|
|
7
|
+
export type * from "./components/robots/SupportedRobot"
|
|
8
|
+
import { SupportedRobot as SR } from "./components/robots/SupportedRobot"
|
|
9
|
+
export const SupportedRobot = externalizeComponent(SR)
|
|
10
|
+
|
|
11
|
+
export type * from "./components/robots/Robot"
|
|
12
|
+
import { Robot as R } from "./components/robots/Robot"
|
|
13
|
+
export const Robot = externalizeComponent(R)
|
|
14
|
+
|
|
15
|
+
export type * from "./components/3d-viewport/PresetEnvironment"
|
|
16
|
+
import { PresetEnvironment as PE } from "./components/3d-viewport/PresetEnvironment"
|
|
17
|
+
export const PresetEnvironment = externalizeComponent(PE)
|
|
18
|
+
|
|
19
|
+
export type * from "./components/3d-viewport/SafetyZonesRenderer"
|
|
20
|
+
import { SafetyZonesRenderer as SZR } from "./components/3d-viewport/SafetyZonesRenderer"
|
|
21
|
+
export const SafetyZonesRenderer = externalizeComponent(SZR)
|
|
22
|
+
|
|
23
|
+
export type * from "./components/jogging/JoggingCartesianAxisControl"
|
|
24
|
+
import { JoggingCartesianAxisControl as JCAC } from "./components/jogging/JoggingCartesianAxisControl"
|
|
25
|
+
export const JoggingCartesianAxisControl = externalizeComponent(JCAC)
|
|
26
|
+
|
|
27
|
+
export type * from "./components/jogging/JoggingJointRotationControl"
|
|
28
|
+
import { JoggingJointRotationControl as JJRC } from "./components/jogging/JoggingJointRotationControl"
|
|
29
|
+
export const JoggingJointRotationControl = externalizeComponent(JJRC)
|
|
30
|
+
|
|
31
|
+
export type { JoggingStore } from "./components/jogging/JoggingStore"
|
|
32
|
+
export type * from "./components/jogging/JoggingPanel"
|
|
33
|
+
import { JoggingPanel as JP } from "./components/jogging/JoggingPanel"
|
|
34
|
+
export const JoggingPanel = externalizeComponent(JP)
|
|
35
|
+
|
|
36
|
+
export type * from "./components/VelocitySlider"
|
|
37
|
+
import { VelocitySlider as VS } from "./components/VelocitySlider"
|
|
38
|
+
export const VelocitySlider = externalizeComponent(VS)
|
|
39
|
+
|
|
10
40
|
export * from "./components/utils/hooks"
|