@adea-ai/ui 0.22.1 → 0.23.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.
Files changed (92) hide show
  1. package/README.md +6 -3
  2. package/dist/components/account-drawer.d.ts +3 -3
  3. package/dist/components/account-drawer.js +119 -19
  4. package/dist/components/on-screen-controls.d.ts +2 -1
  5. package/dist/components/on-screen-controls.js +158 -46
  6. package/dist/components/scene-settings.d.ts +3 -3
  7. package/dist/components/scene-settings.js +247 -28
  8. package/dist/components/theme-provider.d.ts +27 -5
  9. package/dist/components/theme-provider.js +96 -7
  10. package/dist/components/theme-toggle.d.ts +4 -4
  11. package/dist/components/theme-toggle.js +62 -18
  12. package/dist/components/ui/badge.d.ts +4 -3
  13. package/dist/components/ui/badge.js +31 -30
  14. package/dist/components/ui/button.d.ts +4 -3
  15. package/dist/components/ui/button.js +49 -32
  16. package/dist/components/ui/card.d.ts +3 -3
  17. package/dist/components/ui/card.js +25 -6
  18. package/dist/components/ui/dialog.d.ts +13 -13
  19. package/dist/components/ui/dialog.js +94 -26
  20. package/dist/components/ui/drawer.d.ts +23 -15
  21. package/dist/components/ui/drawer.js +109 -64
  22. package/dist/components/ui/dropdown-menu.d.ts +28 -22
  23. package/dist/components/ui/dropdown-menu.js +165 -36
  24. package/dist/components/ui/empty.d.ts +7 -6
  25. package/dist/components/ui/empty.js +78 -26
  26. package/dist/components/ui/field.d.ts +15 -14
  27. package/dist/components/ui/field.js +177 -55
  28. package/dist/components/ui/input.d.ts +2 -2
  29. package/dist/components/ui/input.js +20 -5
  30. package/dist/components/ui/label.d.ts +2 -2
  31. package/dist/components/ui/label.js +15 -5
  32. package/dist/components/ui/radio-group.d.ts +4 -4
  33. package/dist/components/ui/radio-group.js +36 -9
  34. package/dist/components/ui/separator.d.ts +6 -2
  35. package/dist/components/ui/separator.js +18 -6
  36. package/dist/components/ui/skeleton.d.ts +2 -1
  37. package/dist/components/ui/skeleton.js +15 -4
  38. package/dist/components/ui/spinner.d.ts +4 -3
  39. package/dist/components/ui/spinner.js +15 -5
  40. package/dist/components/ui/switch.d.ts +6 -3
  41. package/dist/components/ui/switch.js +57 -6
  42. package/dist/components/ui/tabs.d.ts +6 -5
  43. package/dist/components/ui/tabs.js +52 -24
  44. package/dist/components/ui/toggle-group.d.ts +10 -8
  45. package/dist/components/ui/toggle-group.js +91 -20
  46. package/dist/components/ui/toggle.d.ts +4 -2
  47. package/dist/components/ui/toggle.js +38 -23
  48. package/dist/components/ui/tooltip.d.ts +13 -6
  49. package/dist/components/ui/tooltip.js +51 -14
  50. package/dist/components/version-dialog.d.ts +2 -2
  51. package/dist/components/version-dialog.js +322 -129
  52. package/dist/components/workspace-brand.d.ts +1 -1
  53. package/dist/components/workspace-brand.js +12 -3
  54. package/dist/components/workspace-logo.d.ts +2 -2
  55. package/dist/components/workspace-logo.js +15 -3
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +20 -19
  58. package/dist/lib/utils.js +7 -4
  59. package/dist/lib/version-notes.js +14 -29
  60. package/package.json +18 -16
  61. package/src/components/account-drawer.tsx +48 -67
  62. package/src/components/on-screen-controls.tsx +55 -62
  63. package/src/components/scene-settings.tsx +97 -100
  64. package/src/components/theme-provider.tsx +122 -22
  65. package/src/components/theme-toggle.tsx +29 -54
  66. package/src/components/ui/badge.tsx +14 -23
  67. package/src/components/ui/button.tsx +9 -11
  68. package/src/components/ui/card.tsx +9 -6
  69. package/src/components/ui/dialog.tsx +58 -55
  70. package/src/components/ui/drawer.tsx +84 -125
  71. package/src/components/ui/dropdown-menu.tsx +130 -153
  72. package/src/components/ui/empty.tsx +29 -26
  73. package/src/components/ui/field.tsx +83 -87
  74. package/src/components/ui/input.tsx +8 -8
  75. package/src/components/ui/label.tsx +6 -7
  76. package/src/components/ui/radio-group.tsx +22 -19
  77. package/src/components/ui/separator.tsx +16 -9
  78. package/src/components/ui/skeleton.tsx +6 -3
  79. package/src/components/ui/spinner.tsx +9 -5
  80. package/src/components/ui/switch.tsx +47 -20
  81. package/src/components/ui/tabs.tsx +31 -30
  82. package/src/components/ui/toggle-group.tsx +65 -54
  83. package/src/components/ui/toggle.tsx +9 -12
  84. package/src/components/ui/tooltip.tsx +41 -36
  85. package/src/components/version-dialog.tsx +144 -144
  86. package/src/components/workspace-brand.tsx +5 -5
  87. package/src/components/workspace-logo.tsx +9 -8
  88. package/src/index.tsx +7 -1
  89. package/src/styles/base.css +637 -0
  90. package/src/styles/globals.css +1 -1
  91. package/tsconfig.json +2 -1
  92. package/components.json +0 -19
@@ -1,6 +1,3 @@
1
- 'use client'
2
-
3
- import { useCallback, useEffect, useMemo, useState } from 'react'
4
1
  import {
5
2
  Check,
6
3
  Download,
@@ -9,10 +6,11 @@ import {
9
6
  LoaderCircle,
10
7
  RefreshCw,
11
8
  Sparkles,
12
- } from 'lucide-react'
9
+ } from 'lucide-solid'
10
+ import { createEffect, createMemo, createSignal, Show } from 'solid-js'
13
11
 
14
12
  import { formatReleaseDate, plainTextFromMarkdown } from '#lib/version-notes'
15
- import { Button } from '#components/ui/button'
13
+ import { Button, buttonVariants } from '#components/ui/button'
16
14
  import {
17
15
  Dialog,
18
16
  DialogClose,
@@ -80,74 +78,67 @@ function isUpdateBusy(update: SharedDesktopUpdate | null): boolean {
80
78
  )
81
79
  }
82
80
 
83
- export function VersionDialog({
84
- adapter,
85
- fallbackVersion = '0.1.0',
86
- onOpenChange,
87
- open: controlledOpen,
88
- }: Readonly<{
81
+ export function VersionDialog(props: {
89
82
  adapter: VersionDialogAdapter
90
83
  fallbackVersion?: string
91
84
  onOpenChange?: (open: boolean) => void
92
85
  open?: boolean
93
- }>) {
94
- const [uncontrolledOpen, setUncontrolledOpen] = useState(false)
95
- const open = controlledOpen ?? uncontrolledOpen
96
- const setOpen = useCallback(
97
- (nextOpen: boolean) => {
98
- if (controlledOpen === undefined) setUncontrolledOpen(nextOpen)
99
- onOpenChange?.(nextOpen)
100
- },
101
- [controlledOpen, onOpenChange]
102
- )
103
- const [desktopRuntime, setDesktopRuntime] = useState(false)
104
- const [update, setUpdate] = useState<SharedDesktopUpdate | null>(null)
105
- const [busy, setBusy] = useState(false)
106
- const [error, setError] = useState('')
86
+ }) {
87
+ const [uncontrolledOpen, setUncontrolledOpen] = createSignal(false)
88
+ const open = () => props.open ?? uncontrolledOpen()
89
+ const setOpen = (nextOpen: boolean) => {
90
+ if (props.open === undefined) setUncontrolledOpen(nextOpen)
91
+ props.onOpenChange?.(nextOpen)
92
+ }
107
93
 
108
- useEffect(() => setDesktopRuntime(adapter.isDesktopRuntime()), [adapter])
94
+ const [desktopRuntime, setDesktopRuntime] = createSignal(false)
95
+ const [update, setUpdate] = createSignal<SharedDesktopUpdate | null>(null)
96
+ const [busy, setBusy] = createSignal(false)
97
+ const [error, setError] = createSignal('')
109
98
 
110
- const loadCurrentStatus = useCallback(async () => {
111
- if (!desktopRuntime) return
99
+ const loadCurrentStatus = async () => {
100
+ if (!desktopRuntime()) return
112
101
  try {
113
- setUpdate(await adapter.getStatus())
102
+ setUpdate(await props.adapter.getStatus())
114
103
  } catch (caught) {
115
104
  setError(errorMessage(caught, 'Version status is unavailable'))
116
105
  }
117
- }, [adapter, desktopRuntime])
106
+ }
118
107
 
119
- useEffect(() => {
120
- if (desktopRuntime) void loadCurrentStatus()
121
- }, [desktopRuntime, loadCurrentStatus])
108
+ createEffect(() => setDesktopRuntime(props.adapter.isDesktopRuntime()))
122
109
 
123
- const checkForUpdates = useCallback(async () => {
124
- if (!desktopRuntime) {
110
+ createEffect(() => {
111
+ if (desktopRuntime()) void loadCurrentStatus()
112
+ })
113
+
114
+ const checkForUpdates = async () => {
115
+ if (!desktopRuntime()) {
125
116
  setError('Update checks are available from the desktop app.')
126
117
  return
127
118
  }
128
119
  setBusy(true)
129
120
  setError('')
130
121
  try {
131
- setUpdate(await adapter.check())
122
+ setUpdate(await props.adapter.check())
132
123
  } catch (caught) {
133
124
  setError(errorMessage(caught, 'Could not check for updates'))
134
125
  await loadCurrentStatus()
135
126
  } finally {
136
127
  setBusy(false)
137
128
  }
138
- }, [adapter, desktopRuntime, loadCurrentStatus])
129
+ }
139
130
 
140
- useEffect(() => {
141
- if (!open || !desktopRuntime) return
131
+ createEffect(() => {
132
+ if (!open() || !desktopRuntime()) return
142
133
  let active = true
143
134
  setError('')
144
135
  setBusy(true)
145
136
  void (async () => {
146
137
  try {
147
- const current = await adapter.getStatus()
138
+ const current = await props.adapter.getStatus()
148
139
  if (!active) return
149
140
  setUpdate(current)
150
- const checked = await adapter.check()
141
+ const checked = await props.adapter.check()
151
142
  if (active) setUpdate(checked)
152
143
  } catch (caught) {
153
144
  if (active) setError(errorMessage(caught, 'Could not check for updates'))
@@ -158,15 +149,15 @@ export function VersionDialog({
158
149
  return () => {
159
150
  active = false
160
151
  }
161
- }, [adapter, desktopRuntime, open])
152
+ })
162
153
 
163
154
  const install = async () => {
164
- const version = update?.available_version
155
+ const version = update()?.available_version
165
156
  if (!version) return
166
157
  setBusy(true)
167
158
  setError('')
168
159
  try {
169
- setUpdate(await adapter.install(version))
160
+ setUpdate(await props.adapter.install(version))
170
161
  } catch (caught) {
171
162
  setError(errorMessage(caught, 'Update installation failed'))
172
163
  await loadCurrentStatus()
@@ -175,42 +166,36 @@ export function VersionDialog({
175
166
  }
176
167
  }
177
168
 
178
- const currentChangelog = useMemo(
179
- () => plainTextFromMarkdown(update?.changelog || 'Changelog is loading…'),
180
- [update?.changelog]
169
+ const currentChangelog = createMemo(() =>
170
+ plainTextFromMarkdown(update()?.changelog || 'Changelog is loading…')
181
171
  )
182
- const releaseNotes = update?.release_notes ? plainTextFromMarkdown(update.release_notes) : ''
183
- const busyFromSnapshot = isUpdateBusy(update)
172
+ const releaseNotes = () => {
173
+ const notes = update()?.release_notes
174
+ return notes ? plainTextFromMarkdown(notes) : ''
175
+ }
176
+ const busyFromSnapshot = () => isUpdateBusy(update())
184
177
 
185
178
  return (
186
- <Dialog open={open} onOpenChange={setOpen}>
187
- {controlledOpen === undefined ? (
179
+ <Dialog open={open()} onOpenChange={setOpen}>
180
+ <Show when={props.open === undefined}>
188
181
  <DialogTrigger
189
- render={
190
- <Button
191
- type="button"
192
- variant="ghost"
193
- size="sm"
194
- aria-label="Open version and updates dialog"
195
- aria-haspopup="dialog"
196
- onClick={() => setOpen(true)}
197
- />
198
- }
182
+ class={buttonVariants({ variant: 'ghost', size: 'sm' })}
183
+ aria-label="Open version and updates dialog"
184
+ aria-haspopup="dialog"
185
+ onClick={() => setOpen(true)}
199
186
  >
200
- {update?.phase === 'available' ? (
187
+ <Show when={update()?.phase === 'available'} fallback={<FileText aria-hidden="true" />}>
201
188
  <Sparkles aria-hidden="true" />
202
- ) : (
203
- <FileText aria-hidden="true" />
204
- )}
205
- {phaseLabel(update, fallbackVersion)}
189
+ </Show>
190
+ {phaseLabel(update(), props.fallbackVersion ?? '0.1.0')}
206
191
  </DialogTrigger>
207
- ) : null}
192
+ </Show>
208
193
 
209
- <DialogContent className="max-w-3xl">
194
+ <DialogContent class="max-w-3xl">
210
195
  <DialogHeader>
211
- <div className="flex items-center gap-3">
212
- <span className="flex size-10 items-center justify-center rounded-xl bg-primary text-primary-foreground">
213
- <Sparkles className="size-5" aria-hidden="true" />
196
+ <div class="flex items-center gap-3">
197
+ <span class="flex size-10 items-center justify-center rounded-xl bg-primary text-primary-foreground">
198
+ <Sparkles class="size-5" aria-hidden="true" />
214
199
  </span>
215
200
  <div>
216
201
  <DialogTitle>Version & updates</DialogTitle>
@@ -221,142 +206,157 @@ export function VersionDialog({
221
206
  </div>
222
207
  </DialogHeader>
223
208
 
224
- <div className="min-h-0 space-y-5 overflow-y-auto p-6">
225
- <section className="rounded-xl border bg-background/45 p-4" aria-label="Version status">
226
- <div className="flex flex-wrap items-start justify-between gap-4">
227
- <div className="space-y-1">
228
- <p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
209
+ <div class="min-h-0 space-y-5 overflow-y-auto p-6">
210
+ <section class="rounded-xl border bg-background/45 p-4" aria-label="Version status">
211
+ <div class="flex flex-wrap items-start justify-between gap-4">
212
+ <div class="space-y-1">
213
+ <p class="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
229
214
  Installed version
230
215
  </p>
231
- <p className="text-xl font-semibold tracking-tight">
232
- v{update?.current_version || fallbackVersion}
216
+ <p class="text-xl font-semibold tracking-tight">
217
+ v{update()?.current_version || props.fallbackVersion || '0.1.0'}
233
218
  </p>
234
- <p className="text-sm text-muted-foreground">
235
- {update?.phase === 'current'
236
- ? 'You are running the latest desktop release.'
237
- : update?.phase === 'available' && update.available_version
238
- ? `A newer desktop release, v${update.available_version}, is ready.`
239
- : desktopRuntime
240
- ? 'Check the release channel for the latest signed build.'
241
- : 'Open this dialog inside the desktop app to check for updates.'}
219
+ <p class="text-sm text-muted-foreground">
220
+ <Show
221
+ when={update()?.phase === 'current'}
222
+ fallback={
223
+ <Show
224
+ when={update()?.phase === 'available' && update()?.available_version}
225
+ fallback={
226
+ desktopRuntime()
227
+ ? 'Check the release channel for the latest signed build.'
228
+ : 'Open this dialog inside the desktop app to check for updates.'
229
+ }
230
+ >
231
+ {`A newer desktop release, v${update()?.available_version}, is ready.`}
232
+ </Show>
233
+ }
234
+ >
235
+ You are running the latest desktop release.
236
+ </Show>
242
237
  </p>
243
238
  </div>
244
239
  <Button
245
240
  type="button"
246
241
  variant="outline"
247
242
  size="sm"
248
- disabled={!desktopRuntime || busy || busyFromSnapshot}
243
+ disabled={!desktopRuntime() || busy() || busyFromSnapshot()}
249
244
  onClick={() => void checkForUpdates()}
250
245
  >
251
- {busy || busyFromSnapshot ? (
252
- <LoaderCircle className="animate-spin" aria-hidden="true" />
253
- ) : (
254
- <RefreshCw aria-hidden="true" />
255
- )}
246
+ <Show
247
+ when={busy() || busyFromSnapshot()}
248
+ fallback={<RefreshCw aria-hidden="true" />}
249
+ >
250
+ <LoaderCircle class="animate-spin" aria-hidden="true" />
251
+ </Show>
256
252
  Check latest version
257
253
  </Button>
258
254
  </div>
259
255
  </section>
260
256
 
261
- {update?.phase === 'available' && update.available_version ? (
257
+ <Show when={update()?.phase === 'available' && update()?.available_version}>
262
258
  <section
263
- className="rounded-xl border border-primary/35 bg-primary/8 p-4"
259
+ class="rounded-xl border border-primary/35 bg-primary/8 p-4"
264
260
  aria-label="Available update"
265
261
  >
266
- <div className="flex flex-wrap items-start justify-between gap-4">
267
- <div className="space-y-1">
268
- <p className="flex items-center gap-2 text-sm font-semibold">
269
- <Sparkles className="size-4 text-primary" aria-hidden="true" />
270
- Version {update.available_version} is ready
262
+ <div class="flex flex-wrap items-start justify-between gap-4">
263
+ <div class="space-y-1">
264
+ <p class="flex items-center gap-2 text-sm font-semibold">
265
+ <Sparkles class="size-4 text-primary" aria-hidden="true" />
266
+ Version {update()?.available_version} is ready
271
267
  </p>
272
- <p className="text-sm text-muted-foreground">
268
+ <p class="text-sm text-muted-foreground">
273
269
  The signed installer will be verified before Adea restarts.
274
270
  </p>
275
- {formatReleaseDate(update.release_date) ? (
276
- <p className="text-xs text-muted-foreground">
277
- Released {formatReleaseDate(update.release_date)}
278
- </p>
279
- ) : null}
271
+ <Show when={formatReleaseDate(update()?.release_date ?? null)}>
272
+ {(released) => (
273
+ <p class="text-xs text-muted-foreground">Released {released()}</p>
274
+ )}
275
+ </Show>
280
276
  </div>
281
277
  <Button
282
278
  type="button"
283
279
  size="sm"
284
- disabled={busy || busyFromSnapshot}
280
+ disabled={busy() || busyFromSnapshot()}
285
281
  onClick={() => void install()}
286
282
  >
287
- {busy || busyFromSnapshot ? (
288
- <LoaderCircle className="animate-spin" aria-hidden="true" />
289
- ) : (
290
- <Download aria-hidden="true" />
291
- )}
283
+ <Show
284
+ when={busy() || busyFromSnapshot()}
285
+ fallback={<Download aria-hidden="true" />}
286
+ >
287
+ <LoaderCircle class="animate-spin" aria-hidden="true" />
288
+ </Show>
292
289
  Install and restart
293
290
  </Button>
294
291
  </div>
295
292
  </section>
296
- ) : null}
293
+ </Show>
297
294
 
298
- {update?.phase === 'current' ? (
295
+ <Show when={update()?.phase === 'current'}>
299
296
  <p
300
- className="flex items-center gap-2 text-sm text-emerald-700 dark:text-emerald-300"
297
+ class="flex items-center gap-2 text-sm text-emerald-700 dark:text-emerald-300"
301
298
  role="status"
302
299
  >
303
- <Check className="size-4" aria-hidden="true" />
300
+ <Check class="size-4" aria-hidden="true" />
304
301
  Adea is up to date.
305
302
  </p>
306
- ) : null}
307
- {error ? (
303
+ </Show>
304
+
305
+ <Show when={error()}>
308
306
  <p
309
- className="rounded-lg border border-destructive/35 bg-destructive/8 px-3 py-2 text-sm text-destructive"
307
+ class="rounded-lg border border-destructive/35 bg-destructive/8 px-3 py-2 text-sm text-destructive"
310
308
  role="alert"
311
309
  >
312
- {error}
310
+ {error()}
313
311
  </p>
314
- ) : null}
312
+ </Show>
315
313
 
316
- {releaseNotes ? (
317
- <section className="space-y-2" aria-labelledby="adea-release-notes">
314
+ <Show when={releaseNotes()}>
315
+ <section class="space-y-2" aria-labelledby="adea-release-notes">
318
316
  <div>
319
- <h2 id="adea-release-notes" className="text-sm font-semibold">
317
+ <h2 id="adea-release-notes" class="text-sm font-semibold">
320
318
  What changed in this release
321
319
  </h2>
322
- <p className="text-xs text-muted-foreground">
320
+ <p class="text-xs text-muted-foreground">
323
321
  Release notes are shown as readable text.
324
322
  </p>
325
323
  </div>
326
- <div className="max-h-52 overflow-y-auto whitespace-pre-wrap rounded-xl border bg-background/45 p-4 font-mono text-xs leading-5 text-muted-foreground">
327
- {releaseNotes}
324
+ <div class="max-h-52 overflow-y-auto whitespace-pre-wrap rounded-xl border bg-background/45 p-4 font-mono text-xs leading-5 text-muted-foreground">
325
+ {releaseNotes()}
328
326
  </div>
329
327
  </section>
330
- ) : null}
328
+ </Show>
331
329
 
332
- <section className="space-y-2" aria-labelledby="agent-hq-changelog">
330
+ <section class="space-y-2" aria-labelledby="agent-hq-changelog">
333
331
  <div>
334
- <h2 id="agent-hq-changelog" className="text-sm font-semibold">
332
+ <h2 id="agent-hq-changelog" class="text-sm font-semibold">
335
333
  Installed changelog
336
334
  </h2>
337
- <p className="text-xs text-muted-foreground">
335
+ <p class="text-xs text-muted-foreground">
338
336
  A plain-text history of the installed channel.
339
337
  </p>
340
338
  </div>
341
- <div className="max-h-72 overflow-y-auto whitespace-pre-wrap rounded-xl border bg-background/45 p-4 font-mono text-xs leading-5 text-muted-foreground">
342
- {currentChangelog}
339
+ <div class="max-h-72 overflow-y-auto whitespace-pre-wrap rounded-xl border bg-background/45 p-4 font-mono text-xs leading-5 text-muted-foreground">
340
+ {currentChangelog()}
343
341
  </div>
344
342
  </section>
345
343
  </div>
346
344
 
347
345
  <DialogFooter>
348
- {update?.github_url ? (
349
- <Button
350
- type="button"
351
- variant="ghost"
352
- size="sm"
353
- onClick={() => window.open(update.github_url, '_blank', 'noopener,noreferrer')}
354
- >
355
- <ExternalLink aria-hidden="true" />
356
- View releases
357
- </Button>
358
- ) : null}
359
- <DialogClose render={<Button type="button" variant="outline" size="sm" />}>
346
+ <Show when={update()?.github_url}>
347
+ {(githubUrl) => (
348
+ <Button
349
+ type="button"
350
+ variant="ghost"
351
+ size="sm"
352
+ onClick={() => window.open(githubUrl(), '_blank', 'noopener,noreferrer')}
353
+ >
354
+ <ExternalLink aria-hidden="true" />
355
+ View releases
356
+ </Button>
357
+ )}
358
+ </Show>
359
+ <DialogClose class={buttonVariants({ variant: 'outline', size: 'sm' })}>
360
360
  Close
361
361
  </DialogClose>
362
362
  </DialogFooter>
@@ -3,15 +3,15 @@ export interface WorkspaceBrandProps {
3
3
  eyebrow?: string
4
4
  }
5
5
 
6
- export function WorkspaceBrand({ title, eyebrow = 'AGENT OPERATIONS' }: WorkspaceBrandProps) {
6
+ export function WorkspaceBrand(props: WorkspaceBrandProps) {
7
7
  return (
8
- <div className="workspace-brand">
9
- <div className="workspace-brand__mark" aria-hidden="true">
8
+ <div class="workspace-brand">
9
+ <div class="workspace-brand__mark" aria-hidden="true">
10
10
  <span>HQ</span>
11
11
  </div>
12
12
  <div>
13
- <p className="workspace-eyebrow">{eyebrow}</p>
14
- <h1>{title}</h1>
13
+ <p class="workspace-eyebrow">{props.eyebrow ?? 'AGENT OPERATIONS'}</p>
14
+ <h1>{props.title}</h1>
15
15
  </div>
16
16
  </div>
17
17
  )
@@ -1,20 +1,21 @@
1
- import type { SVGProps } from 'react'
1
+ import { splitProps, type ComponentProps } from 'solid-js'
2
2
 
3
3
  /** The canonical Adea mark used by web, desktop, and dialogs. */
4
- export function WorkspaceLogo(props: SVGProps<SVGSVGElement>) {
4
+ export function WorkspaceLogo(props: ComponentProps<'svg'>) {
5
+ const [local, rest] = splitProps(props, ['class'])
5
6
  return (
6
- <svg viewBox="0 0 64 64" role="img" aria-label="Adea" {...props}>
7
- <rect width="64" height="64" rx="16" className="fill-[var(--workspace-logo-surface)]" />
7
+ <svg viewBox="0 0 64 64" role="img" aria-label="Adea" class={local.class} {...rest}>
8
+ <rect width="64" height="64" rx="16" class="fill-[var(--workspace-logo-surface)]" />
8
9
  <path
9
10
  d="M10 16h7v13h9V16h7v32h-7V36h-9v12h-7z"
10
- className="fill-[var(--workspace-logo-foreground)]"
11
+ class="fill-[var(--workspace-logo-foreground)]"
11
12
  />
12
13
  <path
13
14
  d="M45 16c-7.18 0-13 6-13 16s5.82 16 13 16c7.18 0 13-6 13-16s-5.82-16-13-16Zm0 7c3.42 0 6 3.46 6 9s-2.58 9-6 9-6-3.46-6-9 2.58-9 6-9Z"
14
- fillRule="evenodd"
15
- className="fill-[var(--workspace-logo-foreground)]"
15
+ fill-rule="evenodd"
16
+ class="fill-[var(--workspace-logo-foreground)]"
16
17
  />
17
- <path d="m45 35 11 11-4 4-11-11z" className="fill-[var(--workspace-logo-foreground)]" />
18
+ <path d="m45 35 11 11-4 4-11-11z" class="fill-[var(--workspace-logo-foreground)]" />
18
19
  </svg>
19
20
  )
20
21
  }
package/src/index.tsx CHANGED
@@ -4,7 +4,13 @@ export { Toggle } from './components/ui/toggle'
4
4
  export { ToggleGroup, ToggleGroupItem } from './components/ui/toggle-group'
5
5
  export { RadioGroup, RadioGroupItem } from './components/ui/radio-group'
6
6
  export { ThemeToggle } from './components/theme-toggle'
7
- export { ThemeProvider } from './components/theme-provider'
7
+ export {
8
+ ThemeProvider,
9
+ ThemeScript,
10
+ useTheme,
11
+ type ResolvedTheme,
12
+ type Theme,
13
+ } from './components/theme-provider'
8
14
  export {
9
15
  Drawer,
10
16
  DrawerClose,