@adea-ai/ui 0.95.7 → 0.97.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 (71) hide show
  1. package/dist/components/composites/about-dialog/about-dialog.d.ts +17 -0
  2. package/dist/components/composites/about-dialog/about-dialog.d.ts.map +1 -0
  3. package/dist/components/composites/about-dialog/about-dialog.js +167 -0
  4. package/dist/components/composites/about-dialog/about-dialog.js.map +1 -0
  5. package/dist/components/composites/about-dialog/index.d.ts +3 -0
  6. package/dist/components/composites/about-dialog/index.d.ts.map +1 -0
  7. package/dist/components/composites/about-dialog/index.js +2 -0
  8. package/dist/components/composites/account-menu/account-menu.d.ts +12 -0
  9. package/dist/components/composites/account-menu/account-menu.d.ts.map +1 -1
  10. package/dist/components/composites/account-menu/account-menu.js +91 -49
  11. package/dist/components/composites/account-menu/account-menu.js.map +1 -1
  12. package/dist/components/composites/account-menu/index.d.ts +1 -1
  13. package/dist/components/composites/account-menu/index.d.ts.map +1 -1
  14. package/dist/components/composites/account-menu/index.js +2 -2
  15. package/dist/components/composites/catalog-browser/catalog-browser-group.d.ts +0 -1
  16. package/dist/components/composites/catalog-browser/catalog-browser-group.d.ts.map +1 -1
  17. package/dist/components/composites/catalog-browser/catalog-browser-group.js +16 -18
  18. package/dist/components/composites/catalog-browser/catalog-browser-group.js.map +1 -1
  19. package/dist/components/composites/catalog-browser/catalog-browser.d.ts.map +1 -1
  20. package/dist/components/composites/catalog-browser/catalog-browser.js +7 -7
  21. package/dist/components/composites/catalog-browser/catalog-browser.js.map +1 -1
  22. package/dist/components/composites/catalog-browser/catalog-detail.d.ts +1 -1
  23. package/dist/components/composites/catalog-browser/catalog-detail.d.ts.map +1 -1
  24. package/dist/components/composites/catalog-browser/catalog-detail.js +57 -73
  25. package/dist/components/composites/catalog-browser/catalog-detail.js.map +1 -1
  26. package/dist/components/composites/catalog-browser/catalog-types.d.ts +2 -1
  27. package/dist/components/composites/catalog-browser/catalog-types.d.ts.map +1 -1
  28. package/dist/components/composites/help-center/help-center.d.ts +19 -0
  29. package/dist/components/composites/help-center/help-center.d.ts.map +1 -0
  30. package/dist/components/composites/help-center/help-center.js +135 -0
  31. package/dist/components/composites/help-center/help-center.js.map +1 -0
  32. package/dist/components/composites/help-center/index.d.ts +3 -0
  33. package/dist/components/composites/help-center/index.d.ts.map +1 -0
  34. package/dist/components/composites/help-center/index.js +2 -0
  35. package/dist/components/composites/update-dialog/update-dialog.d.ts +11 -1
  36. package/dist/components/composites/update-dialog/update-dialog.d.ts.map +1 -1
  37. package/dist/components/composites/update-dialog/update-dialog.js +209 -78
  38. package/dist/components/composites/update-dialog/update-dialog.js.map +1 -1
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +4 -2
  42. package/dist/r/about-dialog.json +26 -0
  43. package/dist/r/catalog-browser.json +0 -1
  44. package/dist/r/help-center.json +28 -0
  45. package/dist/r/registry.json +55 -1
  46. package/dist/r/src/components/composites/about-dialog/about-dialog.tsx +161 -0
  47. package/dist/r/src/components/composites/about-dialog/index.ts +2 -0
  48. package/dist/r/src/components/composites/account-menu/account-menu.tsx +64 -12
  49. package/dist/r/src/components/composites/account-menu/index.ts +6 -1
  50. package/dist/r/src/components/composites/catalog-browser/catalog-browser-group.tsx +19 -8
  51. package/dist/r/src/components/composites/catalog-browser/catalog-browser.tsx +5 -3
  52. package/dist/r/src/components/composites/catalog-browser/catalog-detail.tsx +36 -35
  53. package/dist/r/src/components/composites/catalog-browser/catalog-types.ts +2 -1
  54. package/dist/r/src/components/composites/help-center/help-center.tsx +104 -0
  55. package/dist/r/src/components/composites/help-center/index.ts +2 -0
  56. package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +200 -27
  57. package/dist/r/update-dialog.json +1 -0
  58. package/package.json +1 -1
  59. package/registry.json +55 -1
  60. package/src/components/composites/about-dialog/about-dialog.tsx +161 -0
  61. package/src/components/composites/about-dialog/index.ts +2 -0
  62. package/src/components/composites/account-menu/account-menu.tsx +64 -12
  63. package/src/components/composites/account-menu/index.ts +6 -1
  64. package/src/components/composites/catalog-browser/catalog-browser-group.tsx +19 -8
  65. package/src/components/composites/catalog-browser/catalog-browser.tsx +5 -3
  66. package/src/components/composites/catalog-browser/catalog-detail.tsx +36 -35
  67. package/src/components/composites/catalog-browser/catalog-types.ts +2 -1
  68. package/src/components/composites/help-center/help-center.tsx +104 -0
  69. package/src/components/composites/help-center/index.ts +2 -0
  70. package/src/components/composites/update-dialog/update-dialog.tsx +200 -27
  71. package/src/index.ts +2 -0
@@ -64,6 +64,8 @@ export type AccountMenuProps = {
64
64
  platform?: 'desktop' | 'web'
65
65
  /** Whether a session exists. Decides the sign-in/sign-out row. */
66
66
  authenticated: boolean
67
+ /** Local-only applications can omit the session actions altogether. */
68
+ showSession?: boolean
67
69
  /** Disable the session row while a sign-in or sign-out is in flight. */
68
70
  busy?: boolean
69
71
  /** The name shown on the trigger's accessible label. */
@@ -90,6 +92,7 @@ export function AccountMenu(props: AccountMenuProps) {
90
92
  'items',
91
93
  'platform',
92
94
  'authenticated',
95
+ 'showSession',
93
96
  'busy',
94
97
  'label',
95
98
  'onSignIn',
@@ -174,24 +177,73 @@ export function AccountMenu(props: AccountMenuProps) {
174
177
  )}
175
178
  </For>
176
179
  </DropdownMenuGroup>
177
- <DropdownMenuSeparator />
178
- <DropdownMenuGroup>
179
- <DropdownMenuItem
180
- disabled={local.busy}
181
- onSelect={() => (local.authenticated ? local.onSignOut?.() : local.onSignIn?.())}
182
- >
183
- <Show when={local.authenticated} fallback={<LogIn aria-hidden="true" />}>
184
- <LogOut aria-hidden="true" />
185
- </Show>
186
- <span>{local.authenticated ? 'Sign out' : 'Sign in'}</span>
187
- </DropdownMenuItem>
188
- </DropdownMenuGroup>
180
+ <Show when={local.showSession !== false}>
181
+ <DropdownMenuSeparator />
182
+ <DropdownMenuGroup>
183
+ <DropdownMenuItem
184
+ disabled={local.busy}
185
+ onSelect={() => (local.authenticated ? local.onSignOut?.() : local.onSignIn?.())}
186
+ >
187
+ <Show when={local.authenticated} fallback={<LogIn aria-hidden="true" />}>
188
+ <LogOut aria-hidden="true" />
189
+ </Show>
190
+ <span>{local.authenticated ? 'Sign out' : 'Sign in'}</span>
191
+ </DropdownMenuItem>
192
+ </DropdownMenuGroup>
193
+ </Show>
189
194
  </DropdownMenuContent>
190
195
  </DropdownMenu>
191
196
  </Tooltip>
192
197
  )
193
198
  }
194
199
 
200
+ /** The common support menu, with one app-specific entry before the shared items. */
201
+ export function createAppMenuItems(options: {
202
+ primaryItem?: AccountMenuItem
203
+ settingsShortcut?: string
204
+ onAbout?: AccountMenuItem['onSelectAfterClose']
205
+ onHelp?: AccountMenuItem['onSelectAfterClose']
206
+ onFeedback?: AccountMenuItem['onSelectAfterClose']
207
+ onUpdates?: AccountMenuItem['onSelectAfterClose']
208
+ onSettings?: AccountMenuItem['onSelectAfterClose']
209
+ }): AccountMenuItem[] {
210
+ return [
211
+ ...(options.primaryItem ? [options.primaryItem] : []),
212
+ {
213
+ id: 'about',
214
+ label: 'About',
215
+ disabled: !options.onAbout,
216
+ onSelectAfterClose: options.onAbout,
217
+ },
218
+ {
219
+ id: 'help',
220
+ label: 'Help Center',
221
+ disabled: !options.onHelp,
222
+ onSelectAfterClose: options.onHelp,
223
+ },
224
+ {
225
+ id: 'feedback',
226
+ label: 'Send Feedback',
227
+ disabled: !options.onFeedback,
228
+ onSelectAfterClose: options.onFeedback,
229
+ },
230
+ {
231
+ id: 'updates',
232
+ label: 'Updates',
233
+ platform: 'desktop',
234
+ disabled: !options.onUpdates,
235
+ onSelectAfterClose: options.onUpdates,
236
+ },
237
+ {
238
+ id: 'settings',
239
+ label: 'Settings',
240
+ shortcut: options.settingsShortcut,
241
+ disabled: !options.onSettings,
242
+ onSelectAfterClose: options.onSettings,
243
+ },
244
+ ]
245
+ }
246
+
195
247
  function AccountMenuButton(props: ComponentProps<typeof Button>) {
196
248
  return <DropdownMenuTrigger as={Button} {...props} />
197
249
  }
@@ -1 +1,6 @@
1
- export { AccountMenu, type AccountMenuItem, type AccountMenuProps } from './account-menu'
1
+ export {
2
+ AccountMenu,
3
+ createAppMenuItems,
4
+ type AccountMenuItem,
5
+ type AccountMenuProps,
6
+ } from './account-menu'
@@ -33,7 +33,6 @@ function CatalogBrowserRow<Value>(props: {
33
33
  entry: CatalogBrowserEntry<Value>
34
34
  groupId: string
35
35
  installedLabel: string
36
- publishedByLabel: (publisher: string) => string
37
36
  disabled: boolean
38
37
  renderIcon: (value: Value) => JSX.Element
39
38
  onSelect: (entry: CatalogBrowserEntry<Value>, key: string) => void
@@ -59,7 +58,7 @@ function CatalogBrowserRow<Value>(props: {
59
58
  // unimportant `h-auto` loses the stylesheet sort and clamps this
60
59
  // multi-line row to one control line, spilling its content over the
61
60
  // neighbouring rows.
62
- class="h-auto! min-h-row-lg w-full min-w-0 justify-start gap-3 whitespace-normal"
61
+ class="h-auto! min-h-row-lg w-full min-w-0 justify-start gap-3 py-2.5 whitespace-normal"
63
62
  disabled={props.disabled}
64
63
  onClick={() => props.onSelect(props.entry, key)}
65
64
  >
@@ -71,9 +70,18 @@ function CatalogBrowserRow<Value>(props: {
71
70
  <Badge variant="secondary">{props.installedLabel}</Badge>
72
71
  </Show>
73
72
  </span>
74
- <span class="text-muted-foreground line-clamp-2 text-xs">{props.entry.description}</span>
75
- <span class="text-muted-foreground truncate text-2xs">
76
- {props.publishedByLabel(props.entry.publisher)} · {props.entry.category}
73
+ {/* Exactly one content line: the description truncates and the
74
+ publisher and category ride the same line as accent chips. */}
75
+ <span class="flex min-w-0 items-center gap-1.5 text-xs">
76
+ <span class="text-muted-foreground min-w-0 truncate">{props.entry.description}</span>
77
+ <span class="ms-auto flex shrink-0 items-center gap-1">
78
+ <span class="rounded bg-primary-subtle px-1.5 py-0.5 text-2xs font-medium text-primary">
79
+ {props.entry.publisher}
80
+ </span>
81
+ <span class="rounded bg-primary-subtle px-1.5 py-0.5 text-2xs font-medium text-primary">
82
+ {props.entry.category}
83
+ </span>
84
+ </span>
77
85
  </span>
78
86
  </span>
79
87
  <ChevronRight aria-hidden="true" />
@@ -87,7 +95,6 @@ export function CatalogBrowserGroup<Value>(props: {
87
95
  previewCount: number
88
96
  disabled: boolean
89
97
  installedLabel: string
90
- publishedByLabel: (publisher: string) => string
91
98
  showMoreLabel: (entries: readonly CatalogBrowserEntry<Value>[], remainingCount: number) => string
92
99
  showLessLabel: string
93
100
  renderIcon: (value: Value) => JSX.Element
@@ -108,7 +115,12 @@ export function CatalogBrowserGroup<Value>(props: {
108
115
  <h3 id={headingId} class="min-w-0 flex-1 truncate text-sm font-semibold">
109
116
  {props.group.label}
110
117
  </h3>
111
- <Badge variant="outline">{props.group.entries.length}</Badge>
118
+ <Badge
119
+ variant="outline"
120
+ class="border-primary/25 bg-primary-subtle tabular-nums text-primary"
121
+ >
122
+ {props.group.entries.length}
123
+ </Badge>
112
124
  </header>
113
125
  <div id={listId} class="grid min-w-0 grid-cols-1 gap-2 md:grid-cols-2">
114
126
  <For each={rows()}>
@@ -117,7 +129,6 @@ export function CatalogBrowserGroup<Value>(props: {
117
129
  entry={row.item()}
118
130
  groupId={props.group.id}
119
131
  installedLabel={props.installedLabel}
120
- publishedByLabel={props.publishedByLabel}
121
132
  disabled={props.disabled}
122
133
  renderIcon={props.renderIcon}
123
134
  onSelect={props.onSelect}
@@ -131,7 +131,7 @@ export function CatalogBrowser<Value>(props: CatalogBrowserProps<Value>) {
131
131
  <div class="flex min-w-0 shrink-0 flex-wrap items-center gap-2 px-4 pt-2">
132
132
  {props.filterControl}
133
133
  <InputGroup class="min-w-0 flex-1 sm:max-w-md">
134
- <InputGroupAddon>
134
+ <InputGroupAddon class="text-primary">
135
135
  <Search aria-hidden="true" />
136
136
  </InputGroupAddon>
137
137
  <InputGroupInput
@@ -143,7 +143,10 @@ export function CatalogBrowser<Value>(props: CatalogBrowserProps<Value>) {
143
143
  onInput={(event) => props.onQueryChange(event.currentTarget.value)}
144
144
  />
145
145
  </InputGroup>
146
- <span class="text-muted-foreground ms-auto text-sm" role="status">
146
+ <span
147
+ class="text-primary ms-auto text-sm font-medium tabular-nums"
148
+ role="status"
149
+ >
147
150
  {countLabel()}
148
151
  </span>
149
152
  </div>
@@ -200,7 +203,6 @@ export function CatalogBrowser<Value>(props: CatalogBrowserProps<Value>) {
200
203
  previewCount={previewCount()}
201
204
  disabled={props.interactionDisabled ?? false}
202
205
  installedLabel={props.installedLabel}
203
- publishedByLabel={props.publishedByLabel}
204
206
  showMoreLabel={props.showMoreLabel}
205
207
  showLessLabel={props.showLessLabel}
206
208
  renderIcon={props.renderIcon}
@@ -1,6 +1,5 @@
1
1
  import { createUniqueId, Show, type JSX } from 'solid-js'
2
2
  import { Badge } from '../../ui/badge'
3
- import { Card, CardContent, CardFooter, CardHeader } from '../../ui/card'
4
3
 
5
4
  /** Shared item summary and action frame for catalog-owned detail content. */
6
5
  export function CatalogDetail(props: {
@@ -17,48 +16,50 @@ export function CatalogDetail(props: {
17
16
  children?: JSX.Element
18
17
  }) {
19
18
  return (
20
- <article class="grid min-w-0 gap-4" data-catalog-detail>
21
- <Card>
22
- <CardHeader class="flex-row items-start gap-3">
23
- <Show when={props.leading}>
24
- <span class="shrink-0">{props.leading}</span>
25
- </Show>
26
- <div class="grid min-w-0 gap-1.5">
27
- <div class="flex min-w-0 flex-wrap items-center gap-1.5">
28
- <Show when={props.eyebrow}>
29
- <Badge variant="outline">{props.eyebrow}</Badge>
30
- </Show>
31
- <Badge variant="secondary">{props.category}</Badge>
32
- {props.badges}
33
- </div>
34
- <h2 class="text-base leading-tight font-semibold tracking-tight">{props.title}</h2>
35
- <p class="text-muted-foreground text-sm">{props.description}</p>
36
- <p class="text-muted-foreground text-xs">{props.publishedByLabel(props.publisher)}</p>
19
+ <article class="grid min-w-0 gap-2" data-catalog-detail>
20
+ <div class="flex min-w-0 items-start gap-3 rounded-xl border border-border p-3">
21
+ <Show when={props.leading}>
22
+ <span class="shrink-0">{props.leading}</span>
23
+ </Show>
24
+ <div class="grid min-w-0 flex-1 gap-1">
25
+ <div class="flex min-w-0 flex-wrap items-center gap-1.5">
26
+ <Show when={props.eyebrow}>
27
+ <Badge variant="outline">{props.eyebrow}</Badge>
28
+ </Show>
29
+ <Badge variant="secondary">{props.category}</Badge>
30
+ {props.badges}
37
31
  </div>
38
- </CardHeader>
39
- <CardFooter class="flex-wrap justify-between gap-3">
40
- {props.action}
41
- {props.status}
42
- </CardFooter>
43
- </Card>
44
- <div class="grid min-w-0 gap-3">{props.children}</div>
32
+ <h2 class="text-base leading-tight font-semibold tracking-tight">{props.title}</h2>
33
+ <p class="text-muted-foreground text-sm">{props.description}</p>
34
+ <p class="text-muted-foreground text-xs">{props.publishedByLabel(props.publisher)}</p>
35
+ </div>
36
+ <Show when={props.action || props.status}>
37
+ <div class="flex shrink-0 flex-col items-end gap-2">
38
+ {props.action}
39
+ {props.status}
40
+ </div>
41
+ </Show>
42
+ </div>
43
+ <div class="grid min-w-0 gap-2">{props.children}</div>
45
44
  </article>
46
45
  )
47
46
  }
48
47
 
49
- /** A shared surface and heading for host-specific fields, permissions, and copy. */
48
+ /** A shared compact row for host-specific fields, permissions, and copy. */
50
49
  export function CatalogDetailSection(props: { title: string; children?: JSX.Element }) {
51
50
  const headingId = `catalog-detail-section-${createUniqueId()}`
52
51
  return (
53
- <section class="min-w-0" aria-labelledby={headingId}>
54
- <Card>
55
- <CardHeader>
56
- <h3 id={headingId} class="text-sm font-semibold tracking-tight">
57
- {props.title}
58
- </h3>
59
- </CardHeader>
60
- <CardContent class="grid min-w-0 gap-3">{props.children}</CardContent>
61
- </Card>
52
+ <section
53
+ class="grid min-w-0 gap-1.5 rounded-xl border border-border p-3"
54
+ aria-labelledby={headingId}
55
+ >
56
+ <h3
57
+ id={headingId}
58
+ class="text-2xs font-semibold tracking-wider text-muted-foreground uppercase"
59
+ >
60
+ {props.title}
61
+ </h3>
62
+ <div class="grid min-w-0 gap-1.5">{props.children}</div>
62
63
  </section>
63
64
  )
64
65
  }
@@ -73,7 +73,8 @@ export type CatalogBrowserProps<Value> = Readonly<{
73
73
  backLabel: string
74
74
  detailRegionLabel: string
75
75
  installedLabel: string
76
- publishedByLabel: (publisher: string) => string
76
+ /** Optional legacy label: rows now show the bare publisher as an accent chip. */
77
+ publishedByLabel?: (publisher: string) => string
77
78
  showMoreLabel: (entries: readonly CatalogBrowserEntry<Value>[], remainingCount: number) => string
78
79
  showLessLabel: string
79
80
  /** Temporarily disables catalog controls while a host menu owns interaction. */
@@ -0,0 +1,104 @@
1
+ import { createSignal, For, onCleanup, Show } from 'solid-js'
2
+ import { ExternalLink } from 'lucide-solid'
3
+ import { cn } from '#lib/utils'
4
+ import { ActionButton } from '../action-button'
5
+ import { Alert, AlertDescription } from '../../ui/alert'
6
+ import { Card, CardContent, CardHeader } from '../../ui/card'
7
+ import { Kbd, KbdGroup } from '../../ui/kbd'
8
+
9
+ export type HelpShortcut = { label: string; keys: readonly string[] }
10
+ export type HelpLink = { label: string; description?: string; url: string }
11
+ export type HelpCenterProps = {
12
+ appName: string
13
+ shortcuts: readonly HelpShortcut[]
14
+ links: readonly HelpLink[]
15
+ openExternal?: (url: string) => Promise<void>
16
+ class?: string
17
+ }
18
+
19
+ /** A shared help page: real keyboard shortcuts and the application's project resources. */
20
+ export function HelpCenter(props: HelpCenterProps) {
21
+ const [error, setError] = createSignal('')
22
+ let disposed = false
23
+ onCleanup(() => {
24
+ disposed = true
25
+ })
26
+ const openLink = async (url: string) => {
27
+ setError('')
28
+ try {
29
+ await props.openExternal?.(url)
30
+ } catch {
31
+ if (!disposed) setError('Could not open this help resource. Please try again.')
32
+ }
33
+ }
34
+ return (
35
+ <div class={cn('flex min-w-0 flex-col gap-5', props.class)}>
36
+ <div class="flex flex-col gap-2">
37
+ <h1 class="text-xl font-semibold tracking-tight">Help Center</h1>
38
+ <p class="text-sm text-muted-foreground">
39
+ Keyboard shortcuts and resources for {props.appName}.
40
+ </p>
41
+ </div>
42
+ <Card>
43
+ <CardHeader>
44
+ <h2 class="text-base font-semibold text-primary">Keyboard shortcuts</h2>
45
+ </CardHeader>
46
+ <CardContent>
47
+ <ul class="flex flex-col gap-3">
48
+ <For each={props.shortcuts}>
49
+ {(shortcut) => (
50
+ <li class="flex flex-wrap items-center justify-between gap-2">
51
+ <span class="text-sm">{shortcut.label}</span>
52
+ <KbdGroup>
53
+ <For each={shortcut.keys}>{(key) => <Kbd>{key}</Kbd>}</For>
54
+ </KbdGroup>
55
+ </li>
56
+ )}
57
+ </For>
58
+ </ul>
59
+ </CardContent>
60
+ </Card>
61
+ <Card>
62
+ <CardHeader>
63
+ <h2 class="text-base font-semibold text-primary">Project links</h2>
64
+ </CardHeader>
65
+ <CardContent>
66
+ <ul class="flex flex-col gap-4">
67
+ <For each={props.links}>
68
+ {(link) => (
69
+ <li class="flex min-w-0 flex-col items-start gap-1">
70
+ <ActionButton
71
+ as="a"
72
+ variant="link"
73
+ size="sm"
74
+ href={link.url}
75
+ target="_blank"
76
+ rel="noopener noreferrer"
77
+ tooltip={`Open ${link.label} in your browser.`}
78
+ onClick={(event) => {
79
+ if (props.openExternal) {
80
+ event.preventDefault()
81
+ void openLink(link.url)
82
+ }
83
+ }}
84
+ >
85
+ {link.label}
86
+ <ExternalLink aria-hidden="true" />
87
+ </ActionButton>
88
+ <Show when={link.description}>
89
+ <p class="text-sm text-muted-foreground">{link.description}</p>
90
+ </Show>
91
+ </li>
92
+ )}
93
+ </For>
94
+ </ul>
95
+ </CardContent>
96
+ </Card>
97
+ <Show when={error()}>
98
+ <Alert variant="destructive" role="alert">
99
+ <AlertDescription>{error()}</AlertDescription>
100
+ </Alert>
101
+ </Show>
102
+ </div>
103
+ )
104
+ }
@@ -0,0 +1,2 @@
1
+ /** Shared keyboard shortcuts and project resource page. */
2
+ export { HelpCenter, type HelpCenterProps, type HelpShortcut, type HelpLink } from './help-center'