@wandelbots/wandelbots-js-react-components 2.34.1-pr.feature-robot-precondition-list.372.224a5cd → 2.34.1-pr.feature-robot-precondition-list.372.2f4c672

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": "2.34.1-pr.feature-robot-precondition-list.372.224a5cd",
3
+ "version": "2.34.1-pr.feature-robot-precondition-list.372.2f4c672",
4
4
  "description": "React UI toolkit for building applications on top of the Wandelbots platform",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -123,6 +123,12 @@ export const CycleTimer = externalizeComponent(
123
123
  const pausedTimeRef = useRef<number>(0)
124
124
  const [wasRunningBeforeError, setWasRunningBeforeError] = useState(false)
125
125
 
126
+ // Brief animation states for pause and error visual feedback
127
+ const [showPauseAnimation, setShowPauseAnimation] = useState(false)
128
+ const [showErrorAnimation, setShowErrorAnimation] = useState(false)
129
+ const pauseAnimationTimeoutRef = useRef<NodeJS.Timeout | null>(null)
130
+ const errorAnimationTimeoutRef = useRef<NodeJS.Timeout | null>(null)
131
+
126
132
  // Track mode changes for fade transitions
127
133
  const [showLabels, setShowLabels] = useState(true)
128
134
  const prevMaxTimeRef = useRef<number | null | undefined>(undefined)
@@ -236,6 +242,19 @@ export const CycleTimer = externalizeComponent(
236
242
  }
237
243
  setIsRunning(false)
238
244
  setIsPausedState(true)
245
+
246
+ // Trigger brief pause animation
247
+ setShowPauseAnimation(true)
248
+
249
+ // Clear any existing timeout
250
+ if (pauseAnimationTimeoutRef.current) {
251
+ clearTimeout(pauseAnimationTimeoutRef.current)
252
+ }
253
+
254
+ // Reset animation after longer duration
255
+ pauseAnimationTimeoutRef.current = setTimeout(() => {
256
+ setShowPauseAnimation(false)
257
+ }, 800) // 800ms smooth animation
239
258
  }, [isRunning, maxTime, progressInterpolator])
240
259
 
241
260
  const resume = useCallback(() => {
@@ -258,12 +277,31 @@ export const CycleTimer = externalizeComponent(
258
277
  setWasRunningBeforeError(true)
259
278
  pause()
260
279
  }
280
+
281
+ // Trigger brief error animation
282
+ setShowErrorAnimation(true)
283
+
284
+ // Clear any existing timeout
285
+ if (errorAnimationTimeoutRef.current) {
286
+ clearTimeout(errorAnimationTimeoutRef.current)
287
+ }
288
+
289
+ // Reset animation after longer duration
290
+ errorAnimationTimeoutRef.current = setTimeout(() => {
291
+ setShowErrorAnimation(false)
292
+ }, 600) // 600ms smooth animation
261
293
  } else {
262
294
  // Error resolved - resume if was running before error
263
295
  if (wasRunningBeforeError && isPausedState) {
264
296
  setWasRunningBeforeError(false)
265
297
  resume()
266
298
  }
299
+
300
+ // Clear error animation if error is resolved
301
+ setShowErrorAnimation(false)
302
+ if (errorAnimationTimeoutRef.current) {
303
+ clearTimeout(errorAnimationTimeoutRef.current)
304
+ }
267
305
  }
268
306
  }, [
269
307
  hasError,
@@ -374,6 +412,18 @@ export const CycleTimer = externalizeComponent(
374
412
  }
375
413
  }, [progressInterpolator])
376
414
 
415
+ // Cleanup animation timeouts on unmount
416
+ useEffect(() => {
417
+ return () => {
418
+ if (pauseAnimationTimeoutRef.current) {
419
+ clearTimeout(pauseAnimationTimeoutRef.current)
420
+ }
421
+ if (errorAnimationTimeoutRef.current) {
422
+ clearTimeout(errorAnimationTimeoutRef.current)
423
+ }
424
+ }
425
+ }, [])
426
+
377
427
  // Keep interpolator synchronized with static progress when timer is stopped
378
428
  // Ensures correct visual state when component initializes or timer stops
379
429
  useEffect(() => {
@@ -425,8 +475,8 @@ export const CycleTimer = externalizeComponent(
425
475
  display: "flex",
426
476
  alignItems: "center",
427
477
  justifyContent: "center",
428
- opacity: isPausedState ? 0.6 : 1,
429
- transition: "opacity 0.2s ease",
478
+ opacity: showPauseAnimation || showErrorAnimation ? 0.6 : 1,
479
+ transition: "opacity 0.5s ease-out",
430
480
  }}
431
481
  >
432
482
  <svg
@@ -450,6 +500,9 @@ export const CycleTimer = externalizeComponent(
450
500
  }
451
501
  strokeWidth="2"
452
502
  opacity={0.3}
503
+ style={{
504
+ transition: "stroke 0.5s ease-out",
505
+ }}
453
506
  />
454
507
  {/* Progress ring */}
455
508
  <circle
@@ -467,7 +520,8 @@ export const CycleTimer = externalizeComponent(
467
520
  strokeDasharray={`${2 * Math.PI * 8}`}
468
521
  strokeDashoffset={`${2 * Math.PI * 8 * (1 - progressValue / 100)}`}
469
522
  style={{
470
- transition: "stroke-dashoffset 0.1s ease-out",
523
+ transition:
524
+ "stroke-dashoffset 0.1s ease-out, stroke 0.5s ease-out",
471
525
  }}
472
526
  />
473
527
  </svg>
@@ -518,12 +572,13 @@ export const CycleTimer = externalizeComponent(
518
572
  outerRadius="90%"
519
573
  skipAnimation={true}
520
574
  sx={{
521
- opacity: isPausedState ? 0.6 : 1,
522
- transition: "opacity 0.2s ease",
575
+ opacity: showPauseAnimation || showErrorAnimation ? 0.6 : 1,
576
+ transition: "opacity 0.5s ease-out",
523
577
  [`& .MuiGauge-valueArc`]: {
524
578
  fill: hasError
525
579
  ? theme.palette.error.light
526
580
  : theme.palette.success.main,
581
+ transition: "fill 0.5s ease-out",
527
582
  },
528
583
  [`& .MuiGauge-referenceArc`]: {
529
584
  fill: "white",
@@ -28,7 +28,7 @@ function BoundsRefresher({
28
28
  if (!connectedMotionGroup.rapidlyChangingMotionState?.state) {
29
29
  return
30
30
  }
31
-
31
+
32
32
  // Access the rapidly changing motion state to make the autorun reactive to changes
33
33
  connectedMotionGroup.rapidlyChangingMotionState.state.joint_position
34
34
  connectedMotionGroup.rapidlyChangingMotionState.tcp_pose