@viamrobotics/test-widgets 0.10.2 → 0.11.1

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.
Files changed (31) hide show
  1. package/dist/components/audio-properties.svelte +3 -3
  2. package/dist/components/connection-status.svelte +1 -3
  3. package/dist/components/error.svelte +15 -10
  4. package/dist/components/readings-list.svelte +30 -30
  5. package/dist/components/refetch-controller.svelte +2 -2
  6. package/dist/components/widgets/audio-input/audio-input.svelte +85 -83
  7. package/dist/components/widgets/audio-output/audio-output.svelte +93 -91
  8. package/dist/components/widgets/base/base.svelte +39 -37
  9. package/dist/components/widgets/base/move-straight.svelte +1 -1
  10. package/dist/components/widgets/base/set-power.svelte +1 -1
  11. package/dist/components/widgets/base/set-velocity.svelte +1 -1
  12. package/dist/components/widgets/base/spin.svelte +1 -1
  13. package/dist/components/widgets/board/pin-selector.svelte +1 -1
  14. package/dist/components/widgets/board/read-write-pins.svelte +1 -1
  15. package/dist/components/widgets/camera/camera.svelte +6 -5
  16. package/dist/components/widgets/camera/live-or-polling-video.svelte +2 -2
  17. package/dist/components/widgets/discovery/resources-list.svelte +35 -33
  18. package/dist/components/widgets/do-command/do-command.svelte +44 -41
  19. package/dist/components/widgets/gantry/gantry.svelte +102 -98
  20. package/dist/components/widgets/gantry/move-to-position.svelte +1 -1
  21. package/dist/components/widgets/gripper/gripper.svelte +41 -39
  22. package/dist/components/widgets/motor/go-for.svelte +1 -1
  23. package/dist/components/widgets/motor/go-to.svelte +1 -1
  24. package/dist/components/widgets/motor/motor.svelte +88 -86
  25. package/dist/components/widgets/pcd/inputs.svelte +1 -1
  26. package/dist/components/widgets/pcd/pcd-widget.svelte +19 -17
  27. package/dist/components/widgets/servo/servo.svelte +69 -64
  28. package/dist/components/widgets/vision-service/image.svelte +10 -3
  29. package/dist/components/widgets/vision-service/object-point-clouds.svelte +1 -1
  30. package/dist/components/widgets/vision-service/vision-service.svelte +5 -5
  31. package/package.json +16 -6
@@ -31,7 +31,7 @@
31
31
  }
32
32
  </script>
33
33
 
34
- <div class="flex flex-col gap-4">
34
+ <div class="flex shrink-0 flex-col gap-4">
35
35
  <Label>
36
36
  Pin
37
37
 
@@ -33,7 +33,7 @@
33
33
  </script>
34
34
 
35
35
  <div class="flex w-full flex-col gap-6">
36
- <div class="flex w-full gap-16">
36
+ <div class="flex w-full flex-wrap gap-x-16 gap-y-6">
37
37
  <PinSelector
38
38
  value={pinSelection}
39
39
  onChange={handleChangedPinSelection}
@@ -181,7 +181,7 @@
181
181
  </Label>
182
182
  </div>
183
183
  {#if isPlaying}
184
- <div class="flex gap-4 p-4 pb-3">
184
+ <div class="flex flex-wrap gap-4 p-4 pb-3">
185
185
  <RefetchController
186
186
  {refetchInterval}
187
187
  allowLive
@@ -216,8 +216,8 @@
216
216
  {/if}
217
217
  </div>
218
218
  {/if}
219
- <div class="flex h-full w-full gap-4 p-4">
220
- <div class="grow">
219
+ <div class="flex h-full w-full flex-wrap gap-4 p-4">
220
+ <div class="min-w-0 grow basis-80">
221
221
  {#if isPlaying}
222
222
  {#if displayAs360}
223
223
  {#if isLive}
@@ -242,6 +242,7 @@
242
242
  {partID}
243
243
  {resourceName}
244
244
  showResolutionOptions
245
+ videoClass="h-auto max-w-full"
245
246
  {isLive}
246
247
  data={imageQuery.data}
247
248
  error={imageQuery.error}
@@ -252,7 +253,7 @@
252
253
  />
253
254
  {/if}
254
255
  {:else}
255
- <div class="bg-medium flex h-64 w-80 items-center justify-center">
256
+ <div class="bg-medium flex h-64 w-full max-w-80 items-center justify-center">
256
257
  <Button
257
258
  icon="play-circle-outline"
258
259
  variant="dark"
@@ -266,7 +267,7 @@
266
267
  {/if}
267
268
  </div>
268
269
  {#if isPlaying}
269
- <div class="flex flex-col items-start gap-2">
270
+ <div class="flex shrink-0 flex-col items-start gap-2">
270
271
  <ExportScreenshot
271
272
  name={client.current?.name ?? ''}
272
273
  sourceName={selectedSource}
@@ -339,7 +339,7 @@
339
339
  {#if lastError}
340
340
  <ContentRect
341
341
  {contentRect}
342
- cx="bg-medium/50 absolute flex h-64 w-80 items-center justify-center"
342
+ cx="bg-medium/50 absolute flex h-64 w-80 max-w-full items-center justify-center"
343
343
  >
344
344
  <ErrorDisplay
345
345
  class="pb-4"
@@ -349,7 +349,7 @@
349
349
  {:else if isLive ? isStreamLoading : isLoading}
350
350
  <ContentRect
351
351
  {contentRect}
352
- cx="absolute h-64 w-80"
352
+ cx="absolute h-64 w-80 max-w-full"
353
353
  >
354
354
  <Progress />
355
355
  </ContentRect>
@@ -66,44 +66,46 @@
66
66
  <div slot="description">Copy JSON</div>
67
67
  </Tooltip>
68
68
  </div>
69
- <dl class="font-roboto-mono flex flex-col gap-y-4">
70
- {#each sortedData as value (value)}
71
- {@const valueString = JSON.stringify(value, null, 2)}
72
- {@const preview = previews[value.name]}
73
- <div class="flex flex-col gap-y-2">
74
- <div class="flex flex-row">
75
- <dt class="text-default flex w-50 min-w-50 flex-col gap-2 pr-2 font-medium">
76
- <span class="truncate">{value.name}</span>
77
- {#if onAddComponent}
69
+ <div class="@container">
70
+ <dl class="font-roboto-mono flex flex-col gap-y-4">
71
+ {#each sortedData as value (value)}
72
+ {@const valueString = JSON.stringify(value, null, 2)}
73
+ {@const preview = previews[value.name]}
74
+ <div class="flex flex-col gap-y-2">
75
+ <div class="flex flex-col gap-y-2 @lg:flex-row @lg:gap-y-0">
76
+ <dt class="text-default flex flex-col gap-2 pr-2 font-medium @lg:w-50 @lg:min-w-50">
77
+ <span class="truncate">{value.name}</span>
78
+ {#if onAddComponent}
79
+ <Button
80
+ class="w-fit"
81
+ icon="plus"
82
+ onclick={() => onAddComponent(parseComponentConfig(value))}
83
+ >
84
+ Add component
85
+ </Button>
86
+ {/if}
78
87
  <Button
79
88
  class="w-fit"
80
- icon="plus"
81
- onclick={() => onAddComponent(parseComponentConfig(value))}
89
+ icon="content-copy"
90
+ onclick={async () => copyAttributes(value)}
82
91
  >
83
- Add component
92
+ Copy attributes
84
93
  </Button>
85
- {/if}
86
- <Button
87
- class="w-fit"
88
- icon="content-copy"
89
- onclick={async () => copyAttributes(value)}
90
- >
91
- Copy attributes
92
- </Button>
93
- </dt>
94
- <dd class="text-subtle-1 min-w-50">
95
- <div class="border-light bg-extralight relative min-w-50 border px-3 py-2">
96
- <pre class="whitespace-pre-wrap"><code>{valueString}</code></pre>
94
+ </dt>
95
+ <dd class="text-subtle-1 min-w-0 grow">
96
+ <div class="border-light bg-extralight relative border px-3 py-2">
97
+ <pre class="wrap-break-word whitespace-pre-wrap"><code>{valueString}</code></pre>
98
+ </div>
99
+ </dd>
100
+ </div>
101
+ {#if preview}
102
+ <div class="flex w-full @lg:pl-50">
103
+ {@render componentPreview?.(preview)}
97
104
  </div>
98
- </dd>
105
+ {/if}
99
106
  </div>
100
- {#if preview}
101
- <div class="flex w-full pl-50">
102
- {@render componentPreview?.(preview)}
103
- </div>
104
- {/if}
105
- </div>
106
- {/each}
107
- </dl>
107
+ {/each}
108
+ </dl>
109
+ </div>
108
110
  </div>
109
111
  {/if}
@@ -79,51 +79,54 @@
79
79
  {@render header({ input: displayInput, setInput })}
80
80
  </div>
81
81
  {/if}
82
- <div class="flex flex-row items-center justify-between">
83
- <div class="flex w-[45%] flex-col gap-2 border-r py-2">
84
- <span class="text-gray-9 px-4 text-sm font-medium">Input</span>
85
- <CodeEditor
86
- label="input"
87
- language="json"
88
- value={displayInput}
89
- onChange={(nextInput: string) => {
90
- updateInput(nextInput)
91
- }}
92
- class="h-56 overflow-y-auto"
93
- errorMessageID={lastErr ? uid : undefined}
94
- />
95
- </div>
82
+ <div class="@container">
83
+ <div class="flex flex-col @2xl:flex-row">
84
+ <div class="flex min-w-0 flex-col gap-2 py-2 @2xl:flex-1">
85
+ <span class="text-gray-9 px-4 text-sm font-medium">Input</span>
86
+ <CodeEditor
87
+ label="input"
88
+ language="json"
89
+ value={displayInput}
90
+ onChange={(nextInput: string) => {
91
+ updateInput(nextInput)
92
+ }}
93
+ class="h-40 overflow-y-auto @2xl:h-56"
94
+ errorMessageID={lastErr ? uid : undefined}
95
+ />
96
+ </div>
97
+
98
+ <div
99
+ class="flex shrink-0 items-center justify-center border-y px-4 py-2 @2xl:border-x @2xl:border-y-0 @2xl:py-0"
100
+ >
101
+ <Button onclick={execute}>Execute</Button>
102
+ </div>
96
103
 
97
- <Button
98
- class="m-auto"
99
- onclick={execute}>Execute</Button
100
- >
101
-
102
- <div class="flex w-[45%] flex-col gap-2 border-l py-2">
103
- <div class="flex flex-row items-center">
104
- <span class="text-gray-9 px-4 text-sm font-medium">Output</span>
105
- {#if doCommandMutation.isPending}
106
- <Progress
107
- size="medium"
108
- variant="dark"
104
+ <div class="flex min-w-0 flex-col gap-2 py-2 @2xl:flex-1">
105
+ <div class="flex flex-row items-center">
106
+ <span class="text-gray-9 px-4 text-sm font-medium">Output</span>
107
+ {#if doCommandMutation.isPending}
108
+ <Progress
109
+ size="medium"
110
+ variant="dark"
111
+ />
112
+ {/if}
113
+ </div>
114
+ {#if !lastErr}
115
+ <CodeEditor
116
+ label="output"
117
+ language="json"
118
+ value={output}
119
+ readonly
120
+ class="h-40 overflow-y-auto @2xl:h-56"
121
+ />
122
+ {:else}
123
+ <ErrorDisplay
124
+ id={uid}
125
+ class="h-40 px-4 @2xl:h-56"
126
+ lastError={lastErr}
109
127
  />
110
128
  {/if}
111
129
  </div>
112
- {#if !lastErr}
113
- <CodeEditor
114
- label="output"
115
- language="json"
116
- value={output}
117
- readonly
118
- class="h-56 overflow-y-auto"
119
- />
120
- {:else}
121
- <ErrorDisplay
122
- id={uid}
123
- class="h-56 px-4"
124
- lastError={lastErr}
125
- />
126
- {/if}
127
130
  </div>
128
131
  </div>
129
132
  {:else}
@@ -45,113 +45,117 @@
45
45
 
46
46
  <ConnectionStatus {partID}>
47
47
  {#snippet connected()}
48
- <div class="flex flex-row divide-x">
49
- <div class="flex grow flex-row divide-x">
50
- <ApiSection
51
- bottomText="Updates automatically"
52
- aria-labelledby={positionHeadingID}
53
- >
54
- <h3
55
- class="text-subtle-2 flex flex-row items-center gap-1 text-sm"
56
- id={positionHeadingID}
57
- >
58
- <a
59
- href={apiDocsHref('rdk:component:gantry', 'getPosition')}
60
- target="_blank"
61
- rel="noopener noreferrer external"
62
- class="decoration-gray-5 hover:decoration-default text-default font-mono font-semibold underline underline-offset-3"
48
+ <div class="@container">
49
+ <div class="flex flex-col divide-y @4xl:flex-row @4xl:divide-x @4xl:divide-y-0">
50
+ <div class="@container grow">
51
+ <div class="flex flex-col divide-y @2xl:flex-row @2xl:divide-x @2xl:divide-y-0">
52
+ <ApiSection
53
+ bottomText="Updates automatically"
54
+ aria-labelledby={positionHeadingID}
63
55
  >
64
- GetPosition
65
- </a>
66
- and
67
- <a
68
- href={apiDocsHref('rdk:component:gantry', 'getLengths')}
69
- target="_blank"
70
- rel="noopener noreferrer external"
71
- class="decoration-gray-5 hover:decoration-default text-default font-mono font-semibold underline underline-offset-3"
56
+ <h3
57
+ class="text-subtle-2 flex flex-row items-center gap-1 text-sm"
58
+ id={positionHeadingID}
59
+ >
60
+ <a
61
+ href={apiDocsHref('rdk:component:gantry', 'getPosition')}
62
+ target="_blank"
63
+ rel="noopener noreferrer external"
64
+ class="decoration-gray-5 hover:decoration-default text-default font-mono font-semibold underline underline-offset-3"
65
+ >
66
+ GetPosition
67
+ </a>
68
+ and
69
+ <a
70
+ href={apiDocsHref('rdk:component:gantry', 'getLengths')}
71
+ target="_blank"
72
+ rel="noopener noreferrer external"
73
+ class="decoration-gray-5 hover:decoration-default text-default font-mono font-semibold underline underline-offset-3"
74
+ >
75
+ GetLengths
76
+ </a>
77
+ </h3>
78
+ <Queries queries={[positionQuery, lengthsQuery]}>
79
+ {@const positions = positionQuery.data}
80
+ {@const lengths = lengthsQuery.data ?? []}
81
+ {#if positions !== undefined}
82
+ <PositionAndLengths
83
+ {positions}
84
+ {lengths}
85
+ />
86
+ {/if}
87
+ </Queries>
88
+ </ApiSection>
89
+ <ApiSection
90
+ title="MoveToPosition"
91
+ api="rdk:component:gantry"
72
92
  >
73
- GetLengths
74
- </a>
75
- </h3>
76
- <Queries queries={[positionQuery, lengthsQuery]}>
77
- {@const positions = positionQuery.data}
78
- {@const lengths = lengthsQuery.data ?? []}
79
- {#if positions !== undefined}
80
- <PositionAndLengths
81
- {positions}
82
- {lengths}
83
- />
84
- {/if}
85
- </Queries>
86
- </ApiSection>
87
- <ApiSection
88
- title="MoveToPosition"
89
- api="rdk:component:gantry"
90
- >
91
- <Query query={positionQuery}>
92
- {@const positions = positionQuery.data}
93
- {#if positions !== undefined}
94
- <MoveToPosition
95
- {positions}
96
- lastError={moveMutation.error}
97
- moveTo={(newPos: number[], speeds: number[]) => {
98
- moveMutation.mutate([newPos, speeds], {})
99
- }}
100
- />
101
- {/if}
102
- </Query>
103
- </ApiSection>
104
- <div class="flex grow flex-col divide-y">
105
- <ApiSection
106
- title="Quick move"
107
- bottomText="Press a button to execute"
108
- >
109
- <Query
110
- query={positionQuery}
111
- contentCx="h-6"
112
- >
113
- {@const positions = positionQuery.data}
114
- {#if positions !== undefined}
115
- <QuickMove
116
- {positions}
117
- lastError={quickMoveMutation.error}
118
- moveTo={(newPos: number[], speeds: number[]) => {
119
- quickMoveMutation.mutate([newPos, speeds], {})
120
- }}
93
+ <Query query={positionQuery}>
94
+ {@const positions = positionQuery.data}
95
+ {#if positions !== undefined}
96
+ <MoveToPosition
97
+ {positions}
98
+ lastError={moveMutation.error}
99
+ moveTo={(newPos: number[], speeds: number[]) => {
100
+ moveMutation.mutate([newPos, speeds], {})
101
+ }}
102
+ />
103
+ {/if}
104
+ </Query>
105
+ </ApiSection>
106
+ <div class="flex grow flex-col divide-y">
107
+ <ApiSection
108
+ title="Quick move"
109
+ bottomText="Press a button to execute"
110
+ >
111
+ <Query
112
+ query={positionQuery}
113
+ contentCx="h-6"
114
+ >
115
+ {@const positions = positionQuery.data}
116
+ {#if positions !== undefined}
117
+ <QuickMove
118
+ {positions}
119
+ lastError={quickMoveMutation.error}
120
+ moveTo={(newPos: number[], speeds: number[]) => {
121
+ quickMoveMutation.mutate([newPos, speeds], {})
122
+ }}
123
+ />
124
+ {/if}
125
+ </Query>
126
+ </ApiSection>
127
+ <ApiSection
128
+ title="Home"
129
+ api="rdk:component:gantry"
130
+ description="Run the homing sequence"
131
+ >
132
+ <Home
133
+ {partID}
134
+ {resourceName}
121
135
  />
122
- {/if}
123
- </Query>
124
- </ApiSection>
136
+ </ApiSection>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ <div class="flex flex-col divide-y @4xl:ml-auto @4xl:w-full @4xl:max-w-40">
125
141
  <ApiSection
126
- title="Home"
142
+ title="Stop"
127
143
  api="rdk:component:gantry"
128
- description="Run the homing sequence"
129
144
  >
130
- <Home
131
- {partID}
132
- {resourceName}
145
+ <StopButton
146
+ error={stopMutation.error}
147
+ onStop={() => {
148
+ stopMutation.mutate([])
149
+ }}
133
150
  />
134
151
  </ApiSection>
135
- </div>
136
- </div>
137
- <div class="ml-auto flex w-full max-w-40 flex-col divide-y">
138
- <ApiSection
139
- title="Stop"
140
- api="rdk:component:gantry"
141
- >
142
- <StopButton
143
- error={stopMutation.error}
144
- onStop={() => {
145
- stopMutation.mutate([])
146
- }}
152
+ <IsMoving
153
+ client={GantryClient}
154
+ api="rdk:component:gantry"
155
+ {partID}
156
+ {resourceName}
147
157
  />
148
- </ApiSection>
149
- <IsMoving
150
- client={GantryClient}
151
- api="rdk:component:gantry"
152
- {partID}
153
- {resourceName}
154
- />
158
+ </div>
155
159
  </div>
156
160
  </div>
157
161
  {/snippet}
@@ -109,7 +109,7 @@
109
109
  </span>
110
110
  </Tooltip>
111
111
  </span>
112
- <div class="flex flex-row gap-2">
112
+ <div class="flex flex-wrap gap-2">
113
113
  <Button onclick={resetToZero}>Zero</Button>
114
114
  <Button onclick={resetToCurrent}>Current position</Button>
115
115
  </div>
@@ -29,51 +29,53 @@
29
29
 
30
30
  <ConnectionStatus {partID}>
31
31
  {#snippet connected()}
32
- <div class="flex flex-row divide-x">
33
- <span class="flex grow flex-row gap-4">
34
- <ApiSection
35
- title="Open"
36
- api="rdk:component:gripper"
37
- class="grow-0 gap-3 pr-0"
38
- >
39
- <Open
32
+ <div class="@container">
33
+ <div class="flex flex-col divide-y @lg:flex-row @lg:divide-x @lg:divide-y-0">
34
+ <span class="flex grow flex-wrap gap-4">
35
+ <ApiSection
36
+ title="Open"
37
+ api="rdk:component:gripper"
38
+ class="grow-0 gap-3 @xs:pr-0"
39
+ >
40
+ <Open
41
+ {partID}
42
+ {resourceName}
43
+ />
44
+ </ApiSection>
45
+ <ApiSection
46
+ title="Grab"
47
+ api="rdk:component:gripper"
48
+ class="grow-0 gap-3 @xs:pl-0"
49
+ >
50
+ <Grab
51
+ {partID}
52
+ {resourceName}
53
+ />
54
+ </ApiSection>
55
+ </span>
56
+ <div class="flex flex-col divide-y">
57
+ <ApiSection
58
+ title="Stop"
59
+ api="rdk:component:gripper"
60
+ >
61
+ <StopButton
62
+ error={stopMutation.error}
63
+ onStop={() => {
64
+ stopMutation.mutate([])
65
+ }}
66
+ />
67
+ </ApiSection>
68
+ <IsMoving
69
+ client={GripperClient}
70
+ api="rdk:component:gripper"
40
71
  {partID}
41
72
  {resourceName}
42
73
  />
43
- </ApiSection>
44
- <ApiSection
45
- title="Grab"
46
- api="rdk:component:gripper"
47
- class="grow-0 gap-3 pl-0"
48
- >
49
- <Grab
74
+ <IsHoldingSomething
50
75
  {partID}
51
76
  {resourceName}
52
77
  />
53
- </ApiSection>
54
- </span>
55
- <div class="flex flex-col divide-y">
56
- <ApiSection
57
- title="Stop"
58
- api="rdk:component:gripper"
59
- >
60
- <StopButton
61
- error={stopMutation.error}
62
- onStop={() => {
63
- stopMutation.mutate([])
64
- }}
65
- />
66
- </ApiSection>
67
- <IsMoving
68
- client={GripperClient}
69
- api="rdk:component:gripper"
70
- {partID}
71
- {resourceName}
72
- />
73
- <IsHoldingSomething
74
- {partID}
75
- {resourceName}
76
- />
78
+ </div>
77
79
  </div>
78
80
  </div>
79
81
  {/snippet}
@@ -13,7 +13,7 @@
13
13
  let rpm = $state(10)
14
14
  </script>
15
15
 
16
- <div class="flex flex-row gap-4">
16
+ <div class="flex flex-wrap gap-4">
17
17
  <Label cx="max-w-[96px] grow gap-1 text-xs">
18
18
  <p class="flex flex-row gap-1">
19
19
  RPM
@@ -13,7 +13,7 @@
13
13
  let rpm = $state(10)
14
14
  </script>
15
15
 
16
- <div class="flex flex-row gap-4">
16
+ <div class="flex flex-wrap gap-4">
17
17
  <Label cx="max-w-[96px] grow gap-1 text-xs">
18
18
  <p class="flex flex-row gap-1">
19
19
  RPM