@wandelbots/wandelbots-js-react-components 1.33.0 → 1.33.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wandelbots/wandelbots-js-react-components",
3
- "version": "1.33.0",
3
+ "version": "1.33.2",
4
4
  "description": "React UI toolkit for building applications on top of the Wandelbots platform",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -1,22 +1,23 @@
1
1
  import { IconButton, Typography, useTheme } from "@mui/material"
2
2
  import Stack from "@mui/material/Stack"
3
3
  import { observer } from "mobx-react-lite"
4
- import React, { useRef, useState, type ReactNode } from "react"
4
+ import React, { useEffect, useRef, useState, type ReactNode } from "react"
5
5
  import { externalizeComponent } from "../../externalizeComponent"
6
6
  import JogMinus from "../../icons/jog-minus.svg"
7
7
  import JogPlus from "../../icons/jog-plus.svg"
8
8
  import type { AxisControlComponentColors } from "../../themes/themeTypes"
9
9
  import { useAnimationFrame } from "../utils/hooks"
10
-
11
- type Direction = "+" | "-"
10
+ import type { JoggingDirection } from "./JoggingStore"
12
11
 
13
12
  type JoggingCartesianAxisControlProps = {
14
13
  colors?: AxisControlComponentColors
15
14
  label: ReactNode
16
15
  getDisplayedValue: () => string
17
- startJogging: (direction: Direction) => void
16
+ startJogging: (direction: JoggingDirection) => void
18
17
  stopJogging: () => void
19
18
  disabled?: boolean
19
+ /** If set, the corresponding button will be rendered in the pressed state */
20
+ activeJoggingDirection?: JoggingDirection
20
21
  } & React.ComponentProps<typeof Stack>
21
22
 
22
23
  /** A input widget to control an individual cartesian axis */
@@ -29,6 +30,7 @@ export const JoggingCartesianAxisControl = externalizeComponent(
29
30
  startJogging,
30
31
  stopJogging,
31
32
  disabled,
33
+ activeJoggingDirection,
32
34
  ...rest
33
35
  }: JoggingCartesianAxisControlProps) => {
34
36
  useAnimationFrame(() => {
@@ -39,7 +41,21 @@ export const JoggingCartesianAxisControl = externalizeComponent(
39
41
  element.textContent = displayValue
40
42
  })
41
43
  const theme = useTheme()
42
- const [borderColor, setBorderColor] = useState(colors?.borderColor)
44
+
45
+ const [localActiveJoggingDirection, setLocalActiveJoggingDirection] =
46
+ useState<JoggingDirection | null>(null)
47
+
48
+ // Trigger pointer "release" events because e.g. firefox does not trigger pointer events as soon as a component is disabled
49
+ useEffect(() => {
50
+ if (!disabled) {
51
+ return
52
+ }
53
+ onPointerUpOrOut()
54
+ }, [disabled])
55
+
56
+ // Handle both controlled and uncontrolled states
57
+ const showJoggingDirection =
58
+ activeJoggingDirection || localActiveJoggingDirection
43
59
 
44
60
  const valueContainerRef = useRef<HTMLParagraphElement>(null)
45
61
 
@@ -57,17 +73,31 @@ export const JoggingCartesianAxisControl = externalizeComponent(
57
73
  }
58
74
  }
59
75
 
60
- const SxAxisControlButton = {
76
+ const borderColor = showJoggingDirection
77
+ ? colors.buttonBackgroundColor?.pressed
78
+ : colors.borderColor
79
+
80
+ const sxAxisControlButtonBase = {
61
81
  width: "55px",
62
- backgroundColor: colors.buttonBackgroundColor?.default,
63
82
  color: colors.color,
83
+ path: { fill: colors.color },
64
84
  alignContent: "center",
65
85
  fontSize: "37px",
66
- "&:hover": {
86
+ svg: {
87
+ pointerEvents: "none",
88
+ },
89
+ }
90
+
91
+ const sxAxisControlButtonDefault = {
92
+ ...sxAxisControlButtonBase,
93
+ backgroundColor: colors.buttonBackgroundColor?.default,
94
+ ":hover": {
67
95
  backgroundColor: colors.buttonBackgroundColor?.hovered,
68
96
  },
69
- "&:active": {
97
+ ":active": {
70
98
  backgroundColor: colors.buttonBackgroundColor?.pressed,
99
+ color: colors.backgroundColor,
100
+ path: { fill: colors.backgroundColor },
71
101
  },
72
102
  ":disabled": {
73
103
  backgroundColor: colors.buttonBackgroundColor?.disabled,
@@ -75,18 +105,33 @@ export const JoggingCartesianAxisControl = externalizeComponent(
75
105
  },
76
106
  }
77
107
 
78
- function onPointerDown(ev: React.PointerEvent, direction: Direction) {
108
+ const sxAxisControlButtonPressed = {
109
+ ...sxAxisControlButtonBase,
110
+ backgroundColor: colors.buttonBackgroundColor?.pressed,
111
+ color: colors.backgroundColor,
112
+ path: { fill: colors.backgroundColor },
113
+ ":disabled": {
114
+ backgroundColor: colors.buttonBackgroundColor?.pressed,
115
+ "svg path": { fill: theme.palette.action.disabled },
116
+ },
117
+ }
118
+
119
+ function onPointerDown(
120
+ ev: React.PointerEvent,
121
+ direction: JoggingDirection,
122
+ ) {
79
123
  if (disabled) {
80
124
  return
81
125
  }
82
- setBorderColor(colors?.buttonBackgroundColor?.pressed)
126
+
83
127
  if (ev.button === 0) {
128
+ setLocalActiveJoggingDirection(direction)
84
129
  startJogging(direction)
85
130
  }
86
131
  }
87
132
 
88
133
  function onPointerUpOrOut() {
89
- setBorderColor(colors?.borderColor)
134
+ setLocalActiveJoggingDirection(null)
90
135
  stopJogging()
91
136
  }
92
137
 
@@ -100,7 +145,9 @@ export const JoggingCartesianAxisControl = externalizeComponent(
100
145
  onPointerOut={onPointerUpOrOut}
101
146
  size="large"
102
147
  sx={{
103
- ...SxAxisControlButton,
148
+ ...(showJoggingDirection === "-"
149
+ ? sxAxisControlButtonPressed
150
+ : sxAxisControlButtonDefault),
104
151
  borderRadius: "16px 0px 0px 16px",
105
152
  borderLeft: `2px solid ${borderColor ?? "#fff"}`,
106
153
  borderBottom: `2px solid ${borderColor ?? "#fff"}`,
@@ -163,7 +210,9 @@ export const JoggingCartesianAxisControl = externalizeComponent(
163
210
  onPointerOut={onPointerUpOrOut}
164
211
  size="large"
165
212
  sx={{
166
- ...SxAxisControlButton,
213
+ ...(showJoggingDirection === "+"
214
+ ? sxAxisControlButtonPressed
215
+ : sxAxisControlButtonDefault),
167
216
  borderRadius: "0px 16px 16px 0px",
168
217
  borderRight: `2px solid ${borderColor ?? "#fff"}`,
169
218
  borderBottom: `2px solid ${borderColor ?? "#fff"}`,
@@ -17,14 +17,19 @@ import { JoggingActivationRequired } from "./JoggingActivationRequired"
17
17
  import { JoggingCartesianAxisControl } from "./JoggingCartesianAxisControl"
18
18
  import { JoggingJointLimitDetector } from "./JoggingJointLimitDetector"
19
19
  import { JoggingOptions } from "./JoggingOptions"
20
- import type { DiscreteIncrementOption, JoggingStore } from "./JoggingStore"
20
+ import type {
21
+ DiscreteIncrementOption,
22
+ JoggingAxis,
23
+ JoggingDirection,
24
+ JoggingStore,
25
+ } from "./JoggingStore"
21
26
  import { JoggingToggleButtonGroup } from "./JoggingToggleButtonGroup"
22
27
  import { JoggingVelocitySlider } from "./JoggingVelocitySlider"
23
28
 
24
29
  type JoggingCartesianOpts = {
25
- axis: "x" | "y" | "z"
30
+ axis: JoggingAxis
26
31
  motionType: "translate" | "rotate"
27
- direction: "-" | "+"
32
+ direction: JoggingDirection
28
33
  }
29
34
 
30
35
  export const JoggingCartesianTab = observer(
@@ -70,24 +75,32 @@ export const JoggingCartesianTab = observer(
70
75
  if (!tcpPose) return
71
76
 
72
77
  await store.withMotionLock(async () => {
73
- await store.jogger.runIncrementalCartesianMotion({
74
- currentTcpPose: tcpPose,
75
- currentJoints: jointPosition,
76
- coordSystemId: store.activeCoordSystemId,
77
- velocityInRelevantUnits: store.velocityInCurrentUnits,
78
- axis: opts.axis,
79
- direction: opts.direction,
80
- motion:
81
- store.selectedCartesianMotionType === "translate"
82
- ? {
83
- type: "translate",
84
- distanceMm: increment.mm,
85
- }
86
- : {
87
- type: "rotate",
88
- distanceRads: degreesToRadians(increment.degrees),
89
- },
90
- })
78
+ try {
79
+ store.setCurrentIncrementJog({
80
+ axis: opts.axis,
81
+ direction: opts.direction,
82
+ })
83
+ await store.jogger.runIncrementalCartesianMotion({
84
+ currentTcpPose: tcpPose,
85
+ currentJoints: jointPosition,
86
+ coordSystemId: store.activeCoordSystemId,
87
+ velocityInRelevantUnits: store.velocityInCurrentUnits,
88
+ axis: opts.axis,
89
+ direction: opts.direction,
90
+ motion:
91
+ store.selectedCartesianMotionType === "translate"
92
+ ? {
93
+ type: "translate",
94
+ distanceMm: increment.mm,
95
+ }
96
+ : {
97
+ type: "rotate",
98
+ distanceRads: degreesToRadians(increment.degrees),
99
+ },
100
+ })
101
+ } finally {
102
+ store.setCurrentIncrementJog(null)
103
+ }
91
104
  })
92
105
  }
93
106
 
@@ -195,6 +208,11 @@ export const JoggingCartesianTab = observer(
195
208
  key={axis.id}
196
209
  colors={axis.colors}
197
210
  disabled={store.isLocked}
211
+ activeJoggingDirection={
212
+ store.incrementJogInProgress?.axis === axis.id
213
+ ? store.incrementJogInProgress.direction
214
+ : undefined
215
+ }
198
216
  label={
199
217
  <>
200
218
  {axis.icon}
@@ -232,6 +250,11 @@ export const JoggingCartesianTab = observer(
232
250
  key={axis.id}
233
251
  colors={axis.colors}
234
252
  disabled={store.isLocked}
253
+ activeJoggingDirection={
254
+ store.incrementJogInProgress?.axis === axis.id
255
+ ? store.incrementJogInProgress.direction
256
+ : undefined
257
+ }
235
258
  label={
236
259
  <>
237
260
  <RotationIcon />
@@ -27,6 +27,8 @@ const incrementOptions = [
27
27
  ...discreteIncrementOptions,
28
28
  ] as const
29
29
 
30
+ export type JoggingAxis = "x" | "y" | "z"
31
+ export type JoggingDirection = "+" | "-"
30
32
  export type DiscreteIncrementOption = (typeof discreteIncrementOptions)[number]
31
33
  export type IncrementOption = (typeof incrementOptions)[number]
32
34
  export type IncrementOptionId = IncrementOption["id"]
@@ -34,6 +36,11 @@ export type IncrementOptionId = IncrementOption["id"]
34
36
  export const ORIENTATION_IDS = ["coordsys", "tool"]
35
37
  export type OrientationId = (typeof ORIENTATION_IDS)[number]
36
38
 
39
+ export type IncrementJogInProgress = {
40
+ direction: JoggingDirection
41
+ axis: JoggingAxis
42
+ }
43
+
37
44
  export class JoggingStore {
38
45
  selectedTabId: "cartesian" | "joint" | "debug" = "cartesian"
39
46
 
@@ -87,8 +94,11 @@ export class JoggingStore {
87
94
  */
88
95
  selectedCartesianMotionType: "translate" | "rotate" = "translate"
89
96
 
90
- /** True when the API is busy doing a planned increment jog motion */
91
- incrementJoggingInProgress = false
97
+ /**
98
+ * If the jogger is busy running an incremental jog, this will be set
99
+ * with the information about the motion
100
+ */
101
+ incrementJogInProgress: IncrementJogInProgress | null = null
92
102
 
93
103
  /** How fast the robot goes when doing cartesian translate jogging in mm/s */
94
104
  translationVelocityMmPerSec: number = 10
@@ -437,8 +447,8 @@ export class JoggingStore {
437
447
  this.selectedIncrementId = id
438
448
  }
439
449
 
440
- setIncrementJoggingInProgress(inProgress: boolean) {
441
- this.incrementJoggingInProgress = inProgress
450
+ setCurrentIncrementJog(incrementJog: IncrementJogInProgress | null) {
451
+ this.incrementJogInProgress = incrementJog
442
452
  }
443
453
 
444
454
  setVelocityFromSlider(velocity: number) {
@@ -1 +1,3 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="25" height="24" fill="none"><path stroke="#fff" stroke-linecap="round" stroke-width="1.5" d="M18.5 12a6 6 0 1 0-6 6"/><path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m16.5 11 2 2.5 2-2.5"/></svg>
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M8 16C5.76667 16 3.875 15.225 2.325 13.675C0.775 12.125 0 10.2333 0 8C0 5.76667 0.775 3.875 2.325 2.325C3.875 0.775 5.76667 0 8 0C9.15 0 10.25 0.2375 11.3 0.7125C12.35 1.1875 13.25 1.86667 14 2.75V0H16V7H9V5H13.2C12.6667 4.06667 11.9375 3.33333 11.0125 2.8C10.0875 2.26667 9.08333 2 8 2C6.33333 2 4.91667 2.58333 3.75 3.75C2.58333 4.91667 2 6.33333 2 8C2 9.66667 2.58333 11.0833 3.75 12.25C4.91667 13.4167 6.33333 14 8 14C9.28333 14 10.4417 13.6333 11.475 12.9C11.0583 14.1 12.5083 12.1667 11.475 12.9L12.9 14.325C11.4667 15.4417 9.83333 16 8 16Z" fill="white"/>
3
+ </svg>
@@ -212,7 +212,7 @@ export function createDarkTheme(): Theme {
212
212
  hovered: "rgba(241, 77, 66, 1)",
213
213
  disabled: "rgba(241, 77, 66, 1)",
214
214
  },
215
- color: "rgba(255, 255, 255, 1)",
215
+ color: "rgba(255, 198, 198, 1)",
216
216
  },
217
217
  Y: {
218
218
  backgroundColor: "rgba(20, 151, 108, 1)",
@@ -223,7 +223,7 @@ export function createDarkTheme(): Theme {
223
223
  disabled: "rgba(28, 188, 135, 1)",
224
224
  hovered: "rgba(28, 188, 135, 1)",
225
225
  },
226
- color: "rgba(255, 255, 255, 1)",
226
+ color: "rgba(215, 255, 242, 1)",
227
227
  },
228
228
  Z: {
229
229
  backgroundColor: "rgba(1, 87, 155, 1)",
@@ -234,7 +234,7 @@ export function createDarkTheme(): Theme {
234
234
  disabled: "rgba(2, 136, 209, 1)",
235
235
  hovered: "rgba(2, 136, 209, 1)",
236
236
  },
237
- color: "rgba(255, 255, 255, 1)",
237
+ color: "rgba(210, 239, 255, 1)",
238
238
  },
239
239
  },
240
240
  },