@workflow/web-shared 5.0.0-beta.5 → 5.0.0-beta.7

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.
@@ -10,6 +10,7 @@ import {
10
10
  useRef,
11
11
  useState,
12
12
  } from 'react';
13
+ import { useReducedMotion } from '../../hooks/use-reduced-motion';
13
14
  import { ErrorBoundary } from '../error-boundary';
14
15
  import {
15
16
  EntityDetailPanel,
@@ -51,6 +52,7 @@ function useAnimatedViewport(initial: Viewport) {
51
52
  } | null>(null);
52
53
  const currentRef = useRef(initial);
53
54
  currentRef.current = viewport;
55
+ const reducedMotion = useReducedMotion();
54
56
 
55
57
  const cancel = useCallback(() => {
56
58
  if (animRef.current) {
@@ -62,6 +64,13 @@ function useAnimatedViewport(initial: Viewport) {
62
64
  const animateTo = useCallback(
63
65
  (target: Viewport) => {
64
66
  cancel();
67
+
68
+ if (reducedMotion) {
69
+ currentRef.current = target;
70
+ setViewportState(target);
71
+ return;
72
+ }
73
+
65
74
  const from = currentRef.current;
66
75
  const anim = { raf: 0, from, to: target, start: performance.now() };
67
76
 
@@ -79,7 +88,7 @@ function useAnimatedViewport(initial: Viewport) {
79
88
  animRef.current = anim;
80
89
  anim.raf = requestAnimationFrame(tick);
81
90
  },
82
- [cancel]
91
+ [cancel, reducedMotion]
83
92
  );
84
93
 
85
94
  const setViewport = useCallback(
@@ -543,7 +552,7 @@ function NewTraceViewerContent({ trace }: NewTraceViewerProps): ReactNode {
543
552
  <div className="absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-lg bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400">
544
553
  <button
545
554
  type="button"
546
- className="flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100"
555
+ className="flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100"
547
556
  onClick={zoomOut}
548
557
  aria-label="Zoom out"
549
558
  >
@@ -551,7 +560,7 @@ function NewTraceViewerContent({ trace }: NewTraceViewerProps): ReactNode {
551
560
  </button>
552
561
  <button
553
562
  type="button"
554
- className="flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100"
563
+ className="flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100"
555
564
  onClick={resetZoom}
556
565
  aria-label="Reset zoom"
557
566
  >
@@ -559,7 +568,7 @@ function NewTraceViewerContent({ trace }: NewTraceViewerProps): ReactNode {
559
568
  </button>
560
569
  <button
561
570
  type="button"
562
- className="flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100"
571
+ className="flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100"
563
572
  onClick={zoomIn}
564
573
  aria-label="Zoom in"
565
574
  >
@@ -587,9 +596,7 @@ function NewTraceViewerContent({ trace }: NewTraceViewerProps): ReactNode {
587
596
  ? 'bg-green-200 text-green-900'
588
597
  : selectedResource === 'run'
589
598
  ? 'bg-blue-200 text-blue-900'
590
- : selectedResource === 'hook'
591
- ? 'bg-yellow-200 text-yellow-900'
592
- : 'bg-gray-200 text-gray-900'
599
+ : 'bg-gray-200 text-gray-900'
593
600
  }`}
594
601
  >
595
602
  {selectedResource.charAt(0).toUpperCase() +
@@ -130,18 +130,50 @@ export function computeSpanGaps(
130
130
 
131
131
  export const RESOURCE_COLORS: Record<
132
132
  string,
133
- { bar: string; errorBar?: string }
133
+ {
134
+ bg: string;
135
+ border: string;
136
+ errorBg?: string;
137
+ errorBorder?: string;
138
+ }
134
139
  > = {
135
- run: { bar: 'var(--ds-blue-700)', errorBar: 'var(--ds-red-700)' },
136
- step: { bar: 'var(--ds-green-700)', errorBar: 'var(--ds-red-700)' },
137
- hook: { bar: 'var(--ds-amber-700)', errorBar: 'var(--ds-red-700)' },
138
- sleep: { bar: 'var(--ds-purple-700)', errorBar: 'var(--ds-red-700)' },
139
- default: { bar: 'var(--ds-gray-500)', errorBar: 'var(--ds-red-700)' },
140
+ run: {
141
+ bg: 'var(--ds-blue-200)',
142
+ border: 'var(--ds-blue-500)',
143
+ errorBg: 'var(--ds-red-200)',
144
+ errorBorder: 'var(--ds-red-500)',
145
+ },
146
+ step: {
147
+ bg: 'var(--ds-green-200)',
148
+ border: 'var(--ds-green-500)',
149
+ errorBg: 'var(--ds-red-200)',
150
+ errorBorder: 'var(--ds-red-500)',
151
+ },
152
+ hook: {
153
+ bg: 'var(--ds-amber-200)',
154
+ border: 'var(--ds-amber-500)',
155
+ errorBg: 'var(--ds-red-200)',
156
+ errorBorder: 'var(--ds-red-500)',
157
+ },
158
+ sleep: {
159
+ bg: 'var(--ds-purple-200)',
160
+ border: 'var(--ds-purple-500)',
161
+ errorBg: 'var(--ds-red-200)',
162
+ errorBorder: 'var(--ds-red-500)',
163
+ },
164
+ default: {
165
+ bg: 'var(--ds-gray-200)',
166
+ border: 'var(--ds-gray-500)',
167
+ errorBg: 'var(--ds-red-200)',
168
+ errorBorder: 'var(--ds-red-500)',
169
+ },
140
170
  };
141
171
 
142
172
  export function getResourceColor(resource: string): {
143
- bar: string;
144
- errorBar?: string;
173
+ bg: string;
174
+ border: string;
175
+ errorBg?: string;
176
+ errorBorder?: string;
145
177
  } {
146
178
  return RESOURCE_COLORS[resource] ?? RESOURCE_COLORS.default;
147
179
  }
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+
5
+ const QUERY = '(prefers-reduced-motion: reduce)';
6
+
7
+ /**
8
+ * Hook that detects whether the user has requested reduced motion and reacts
9
+ * to changes. Mirrors the `prefers-reduced-motion: reduce` media query so
10
+ * components can skip or shorten animations for users with motion
11
+ * sensitivities (e.g. vestibular disorders).
12
+ *
13
+ * @returns `true` if the user prefers reduced motion, `false` otherwise
14
+ */
15
+ export const useReducedMotion = (): boolean => {
16
+ const [reduced, setReduced] = useState(() => {
17
+ if (typeof window === 'undefined' || !window.matchMedia) return false;
18
+ return window.matchMedia(QUERY).matches;
19
+ });
20
+
21
+ useEffect(() => {
22
+ if (typeof window === 'undefined' || !window.matchMedia) return;
23
+
24
+ const media = window.matchMedia(QUERY);
25
+ const onChange = (): void => setReduced(media.matches);
26
+
27
+ media.addEventListener('change', onChange);
28
+ onChange();
29
+
30
+ return () => media.removeEventListener('change', onChange);
31
+ }, []);
32
+
33
+ return reduced;
34
+ };