@adea-ai/ui 0.100.2 → 0.101.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.
- package/dist/components/composites/about-dialog/about-dialog.d.ts.map +1 -1
- package/dist/components/composites/about-dialog/about-dialog.js +2 -1
- package/dist/components/composites/about-dialog/about-dialog.js.map +1 -1
- package/dist/components/composites/account-menu/account-menu.d.ts +7 -0
- package/dist/components/composites/account-menu/account-menu.d.ts.map +1 -1
- package/dist/components/composites/account-menu/account-menu.js +116 -89
- package/dist/components/composites/account-menu/account-menu.js.map +1 -1
- package/dist/components/composites/help-center/help-center.d.ts.map +1 -1
- package/dist/components/composites/help-center/help-center.js +26 -21
- package/dist/components/composites/help-center/help-center.js.map +1 -1
- package/dist/components/composites/settings/settings.d.ts.map +1 -1
- package/dist/components/composites/settings/settings.js +43 -36
- package/dist/components/composites/settings/settings.js.map +1 -1
- package/dist/components/composites/stat/stat.d.ts.map +1 -1
- package/dist/components/composites/stat/stat.js +46 -35
- package/dist/components/composites/stat/stat.js.map +1 -1
- package/dist/components/composites/update-dialog/update-dialog.d.ts.map +1 -1
- package/dist/components/composites/update-dialog/update-dialog.js +73 -58
- package/dist/components/composites/update-dialog/update-dialog.js.map +1 -1
- package/dist/components/layout/page/page.d.ts.map +1 -1
- package/dist/components/layout/page/page.js +19 -13
- package/dist/components/layout/page/page.js.map +1 -1
- package/dist/components/theme/appearance-panel.d.ts.map +1 -1
- package/dist/components/theme/appearance-panel.js +37 -18
- package/dist/components/theme/appearance-panel.js.map +1 -1
- package/dist/components/ui/alert-dialog/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/alert-dialog/alert-dialog.js +5 -1
- package/dist/components/ui/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/components/ui/card/card.d.ts.map +1 -1
- package/dist/components/ui/card/card.js +5 -1
- package/dist/components/ui/card/card.js.map +1 -1
- package/dist/components/ui/chart/chart-options.d.ts +3 -2
- package/dist/components/ui/chart/chart-options.d.ts.map +1 -1
- package/dist/components/ui/chart/chart-options.js +30 -9
- package/dist/components/ui/chart/chart-options.js.map +1 -1
- package/dist/components/ui/chart/chart.d.ts +4 -9
- package/dist/components/ui/chart/chart.d.ts.map +1 -1
- package/dist/components/ui/chart/chart.js +65 -10
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog/dialog.js +5 -1
- package/dist/components/ui/dialog/dialog.js.map +1 -1
- package/dist/components/ui/drawer/drawer.d.ts.map +1 -1
- package/dist/components/ui/drawer/drawer.js +5 -1
- package/dist/components/ui/drawer/drawer.js.map +1 -1
- package/dist/components/ui/field/field.d.ts.map +1 -1
- package/dist/components/ui/field/field.js +2 -1
- package/dist/components/ui/field/field.js.map +1 -1
- package/dist/components/ui/item/item.d.ts +1 -1
- package/dist/components/ui/navigation-menu/navigation-menu.d.ts.map +1 -1
- package/dist/components/ui/navigation-menu/navigation-menu.js +8 -7
- package/dist/components/ui/navigation-menu/navigation-menu.js.map +1 -1
- package/dist/components/ui/sheet/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet/sheet.js +5 -1
- package/dist/components/ui/sheet/sheet.js.map +1 -1
- package/dist/components/ui/tabs/tabs.d.ts +13 -0
- package/dist/components/ui/tabs/tabs.d.ts.map +1 -1
- package/dist/components/ui/tabs/tabs.js +15 -1
- package/dist/components/ui/tabs/tabs.js.map +1 -1
- package/dist/components/ui/toast/toast.d.ts.map +1 -1
- package/dist/components/ui/toast/toast.js +6 -2
- package/dist/components/ui/toast/toast.js.map +1 -1
- package/dist/components/ui/typography/index.d.ts +3 -0
- package/dist/components/ui/typography/index.d.ts.map +1 -0
- package/dist/components/ui/typography/index.js +2 -0
- package/dist/components/ui/typography/typography.d.ts +84 -0
- package/dist/components/ui/typography/typography.d.ts.map +1 -0
- package/dist/components/ui/typography/typography.js +179 -0
- package/dist/components/ui/typography/typography.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/r/account-menu.json +1 -0
- package/dist/r/alert-dialog.json +1 -0
- package/dist/r/card.json +1 -0
- package/dist/r/dialog.json +1 -0
- package/dist/r/drawer.json +1 -0
- package/dist/r/field.json +1 -0
- package/dist/r/help-center.json +1 -0
- package/dist/r/page.json +1 -0
- package/dist/r/registry.json +37 -0
- package/dist/r/settings.json +1 -0
- package/dist/r/sheet.json +1 -0
- package/dist/r/src/components/composites/about-dialog/about-dialog.tsx +3 -2
- package/dist/r/src/components/composites/account-menu/account-menu.tsx +105 -66
- package/dist/r/src/components/composites/help-center/help-center.tsx +2 -1
- package/dist/r/src/components/composites/settings/settings.tsx +4 -1
- package/dist/r/src/components/composites/stat/stat.tsx +7 -2
- package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +36 -24
- package/dist/r/src/components/layout/page/page.tsx +3 -2
- package/dist/r/src/components/theme/appearance-panel.tsx +13 -4
- package/dist/r/src/components/ui/alert-dialog/alert-dialog.tsx +2 -1
- package/dist/r/src/components/ui/card/card.tsx +2 -1
- package/dist/r/src/components/ui/chart/chart-options.ts +35 -7
- package/dist/r/src/components/ui/chart/chart.tsx +65 -12
- package/dist/r/src/components/ui/dialog/dialog.tsx +2 -1
- package/dist/r/src/components/ui/drawer/drawer.tsx +2 -1
- package/dist/r/src/components/ui/field/field.tsx +2 -3
- package/dist/r/src/components/ui/navigation-menu/navigation-menu.tsx +27 -20
- package/dist/r/src/components/ui/sheet/sheet.tsx +5 -1
- package/dist/r/src/components/ui/tabs/tabs.tsx +18 -1
- package/dist/r/src/components/ui/toast/toast.tsx +7 -6
- package/dist/r/src/components/ui/typography/index.ts +9 -0
- package/dist/r/src/components/ui/typography/typography.tsx +205 -0
- package/dist/r/stat.json +1 -0
- package/dist/r/theming.json +1 -0
- package/dist/r/typography.json +24 -0
- package/dist/r/update-dialog.json +1 -0
- package/package.json +1 -1
- package/registry.json +37 -0
- package/src/components/composites/about-dialog/about-dialog.tsx +3 -2
- package/src/components/composites/account-menu/account-menu.tsx +105 -66
- package/src/components/composites/help-center/help-center.tsx +2 -1
- package/src/components/composites/settings/settings.tsx +4 -1
- package/src/components/composites/stat/stat.tsx +7 -2
- package/src/components/composites/update-dialog/update-dialog.tsx +36 -24
- package/src/components/layout/page/page.tsx +3 -2
- package/src/components/theme/appearance-panel.tsx +13 -4
- package/src/components/ui/alert-dialog/alert-dialog.tsx +2 -1
- package/src/components/ui/card/card.tsx +2 -1
- package/src/components/ui/chart/chart-options.ts +35 -7
- package/src/components/ui/chart/chart.tsx +65 -12
- package/src/components/ui/dialog/dialog.tsx +2 -1
- package/src/components/ui/drawer/drawer.tsx +2 -1
- package/src/components/ui/field/field.tsx +2 -3
- package/src/components/ui/navigation-menu/navigation-menu.tsx +27 -20
- package/src/components/ui/sheet/sheet.tsx +5 -1
- package/src/components/ui/tabs/tabs.tsx +18 -1
- package/src/components/ui/toast/toast.tsx +7 -6
- package/src/components/ui/typography/index.ts +9 -0
- package/src/components/ui/typography/typography.tsx +205 -0
- package/src/index.ts +1 -0
|
@@ -13,6 +13,7 @@ import type { ComponentProps, JSX } from 'solid-js'
|
|
|
13
13
|
import { For, Show, createSignal, onCleanup, splitProps } from 'solid-js'
|
|
14
14
|
import { cn } from '../../../lib/utils'
|
|
15
15
|
import { Button, type ButtonProps } from '../../ui/button/button'
|
|
16
|
+
import { SideRailButton } from '../../layout/side-rail/side-rail'
|
|
16
17
|
import {
|
|
17
18
|
DropdownMenu,
|
|
18
19
|
DropdownMenuContent,
|
|
@@ -70,6 +71,13 @@ export type AccountMenuProps = {
|
|
|
70
71
|
hideArrow?: boolean
|
|
71
72
|
/** The trigger size. Icon-only menus default to the standard icon size. */
|
|
72
73
|
size?: ButtonProps['size']
|
|
74
|
+
/**
|
|
75
|
+
* Render the trigger as a `SideRailButton` row instead of a bare icon
|
|
76
|
+
* button: same geometry, hover treatment, and flush collapsed-rail tip as
|
|
77
|
+
* every other entry in the surrounding rail. The component's own tooltip
|
|
78
|
+
* is skipped — the rail row owns its help.
|
|
79
|
+
*/
|
|
80
|
+
railTrigger?: boolean
|
|
73
81
|
/** The entries above the separator. */
|
|
74
82
|
items: readonly AccountMenuItem[]
|
|
75
83
|
/** Which platform this is rendered on, for items that declare one. */
|
|
@@ -104,6 +112,7 @@ export function AccountMenu(props: AccountMenuProps) {
|
|
|
104
112
|
'gutter',
|
|
105
113
|
'hideArrow',
|
|
106
114
|
'size',
|
|
115
|
+
'railTrigger',
|
|
107
116
|
'items',
|
|
108
117
|
'platform',
|
|
109
118
|
'authenticated',
|
|
@@ -133,83 +142,113 @@ export function AccountMenu(props: AccountMenuProps) {
|
|
|
133
142
|
const visible = () =>
|
|
134
143
|
local.items.filter((item) => !item.platform || item.platform === (local.platform ?? 'desktop'))
|
|
135
144
|
|
|
136
|
-
return
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
145
|
+
// Built by reference at each return, not once up front: Solid fixes a node's
|
|
146
|
+
// owner chain when the JSX expression runs, and an eagerly created tree would
|
|
147
|
+
// never see the Tooltip provider below — Kobalte's TooltipTrigger then throws
|
|
148
|
+
// `useTooltipContext must be used within a Tooltip component`.
|
|
149
|
+
const menu = () => (
|
|
150
|
+
<DropdownMenu
|
|
151
|
+
modal={false}
|
|
152
|
+
placement={local.placement ?? 'top-start'}
|
|
153
|
+
gutter={local.gutter}
|
|
154
|
+
onOpenChange={(open) => {
|
|
155
|
+
setMenuOpen(open)
|
|
156
|
+
if (open) setTooltipOpen(false)
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
<Show
|
|
160
|
+
when={local.railTrigger}
|
|
161
|
+
fallback={
|
|
162
|
+
<TooltipTrigger
|
|
163
|
+
as={AccountMenuButton}
|
|
164
|
+
ref={(element: HTMLButtonElement) => (trigger = element)}
|
|
165
|
+
variant="ghost"
|
|
166
|
+
size={local.size ?? 'icon-md'}
|
|
167
|
+
class={cn('text-muted-foreground', local.class)}
|
|
168
|
+
aria-label={local.label ?? 'Account and settings'}
|
|
169
|
+
onFocus={() => local.onIntent?.()}
|
|
170
|
+
onPointerEnter={() => local.onIntent?.()}
|
|
171
|
+
{...rest}
|
|
172
|
+
>
|
|
173
|
+
<UserRound aria-hidden="true" />
|
|
174
|
+
</TooltipTrigger>
|
|
175
|
+
}
|
|
146
176
|
>
|
|
147
|
-
|
|
148
|
-
|
|
177
|
+
{/* Rail parity: the trigger is a SideRailButton row — the same
|
|
178
|
+
geometry and flush collapsed-rail tip as every other rail entry —
|
|
179
|
+
so the composite's own tooltip stays out of the way. */}
|
|
180
|
+
<DropdownMenuTrigger
|
|
181
|
+
as={SideRailButton}
|
|
149
182
|
ref={(element: HTMLButtonElement) => (trigger = element)}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
class={cn('text-muted-foreground', local.class)}
|
|
153
|
-
aria-label={local.label ?? 'Account and settings'}
|
|
183
|
+
label={local.label ?? 'Account and settings'}
|
|
184
|
+
class={local.class}
|
|
154
185
|
onFocus={() => local.onIntent?.()}
|
|
155
186
|
onPointerEnter={() => local.onIntent?.()}
|
|
156
187
|
{...rest}
|
|
157
188
|
>
|
|
158
189
|
<UserRound aria-hidden="true" />
|
|
159
|
-
</
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
190
|
+
</DropdownMenuTrigger>
|
|
191
|
+
</Show>
|
|
192
|
+
<DropdownMenuContent
|
|
193
|
+
hideArrow={local.hideArrow}
|
|
194
|
+
class="min-w-56 max-h-(--kb-popper-available-height) overflow-x-hidden overflow-y-auto"
|
|
195
|
+
onCloseAutoFocus={(event) => {
|
|
196
|
+
const selection = pendingAfterClose
|
|
197
|
+
pendingAfterClose = undefined
|
|
198
|
+
if (!selection) return
|
|
167
199
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
<DropdownMenuItem
|
|
181
|
-
disabled={item.disabled}
|
|
182
|
-
onSelect={() => {
|
|
183
|
-
pendingAfterClose = item.onSelectAfterClose
|
|
184
|
-
? { callback: item.onSelectAfterClose }
|
|
185
|
-
: undefined
|
|
186
|
-
item.onSelect?.()
|
|
187
|
-
}}
|
|
188
|
-
shortcut={item.shortcut}
|
|
189
|
-
keyshortcuts={item.keyshortcuts}
|
|
190
|
-
>
|
|
191
|
-
{item.icon ?? renderFallbackIcon(item.id)}
|
|
192
|
-
<span>{item.label}</span>
|
|
193
|
-
</DropdownMenuItem>
|
|
194
|
-
)}
|
|
195
|
-
</For>
|
|
196
|
-
</DropdownMenuGroup>
|
|
197
|
-
<Show when={local.showSession !== false}>
|
|
198
|
-
<DropdownMenuSeparator />
|
|
199
|
-
<DropdownMenuGroup>
|
|
200
|
+
event.preventDefault()
|
|
201
|
+
scheduledAfterClose = selection
|
|
202
|
+
queueMicrotask(() => {
|
|
203
|
+
if (scheduledAfterClose !== selection) return
|
|
204
|
+
scheduledAfterClose = undefined
|
|
205
|
+
selection.callback(trigger)
|
|
206
|
+
})
|
|
207
|
+
}}
|
|
208
|
+
>
|
|
209
|
+
<DropdownMenuGroup>
|
|
210
|
+
<For each={visible()}>
|
|
211
|
+
{(item) => (
|
|
200
212
|
<DropdownMenuItem
|
|
201
|
-
disabled={
|
|
202
|
-
onSelect={() =>
|
|
213
|
+
disabled={item.disabled}
|
|
214
|
+
onSelect={() => {
|
|
215
|
+
pendingAfterClose = item.onSelectAfterClose
|
|
216
|
+
? { callback: item.onSelectAfterClose }
|
|
217
|
+
: undefined
|
|
218
|
+
item.onSelect?.()
|
|
219
|
+
}}
|
|
220
|
+
shortcut={item.shortcut}
|
|
221
|
+
keyshortcuts={item.keyshortcuts}
|
|
203
222
|
>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
</Show>
|
|
207
|
-
<span>{local.authenticated ? 'Sign out' : 'Sign in'}</span>
|
|
223
|
+
{item.icon ?? renderFallbackIcon(item.id)}
|
|
224
|
+
<span>{item.label}</span>
|
|
208
225
|
</DropdownMenuItem>
|
|
209
|
-
|
|
210
|
-
</
|
|
211
|
-
</
|
|
212
|
-
|
|
226
|
+
)}
|
|
227
|
+
</For>
|
|
228
|
+
</DropdownMenuGroup>
|
|
229
|
+
<Show when={local.showSession !== false}>
|
|
230
|
+
<DropdownMenuSeparator />
|
|
231
|
+
<DropdownMenuGroup>
|
|
232
|
+
<DropdownMenuItem
|
|
233
|
+
disabled={local.busy}
|
|
234
|
+
onSelect={() => (local.authenticated ? local.onSignOut?.() : local.onSignIn?.())}
|
|
235
|
+
>
|
|
236
|
+
<Show when={local.authenticated} fallback={<LogIn aria-hidden="true" />}>
|
|
237
|
+
<LogOut aria-hidden="true" />
|
|
238
|
+
</Show>
|
|
239
|
+
<span>{local.authenticated ? 'Sign out' : 'Sign in'}</span>
|
|
240
|
+
</DropdownMenuItem>
|
|
241
|
+
</DropdownMenuGroup>
|
|
242
|
+
</Show>
|
|
243
|
+
</DropdownMenuContent>
|
|
244
|
+
</DropdownMenu>
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
if (local.railTrigger) return menu()
|
|
248
|
+
|
|
249
|
+
return (
|
|
250
|
+
<Tooltip open={tooltipOpen()} onOpenChange={(open) => setTooltipOpen(open && !menuOpen())}>
|
|
251
|
+
{menu()}
|
|
213
252
|
{/* Both overlays own a Popper context; the tooltip must stay outside the menu root. */}
|
|
214
253
|
<TooltipContent placement="top">{local.label ?? 'Account and settings'}</TooltipContent>
|
|
215
254
|
</Tooltip>
|
|
@@ -5,6 +5,7 @@ import { ActionButton } from '../action-button'
|
|
|
5
5
|
import { Alert, AlertDescription } from '../../ui/alert'
|
|
6
6
|
import { Card, CardContent, CardHeader } from '../../ui/card'
|
|
7
7
|
import { Kbd, KbdGroup } from '../../ui/kbd'
|
|
8
|
+
import { Heading } from '../../ui/typography'
|
|
8
9
|
|
|
9
10
|
export type HelpShortcut = { label: string; keys: readonly string[] }
|
|
10
11
|
export type HelpLink = { label: string; description?: string; url: string }
|
|
@@ -37,7 +38,7 @@ export function HelpCenter(props: HelpCenterProps) {
|
|
|
37
38
|
<div class={cn('flex min-w-0 flex-col gap-5', props.class)}>
|
|
38
39
|
<Show when={props.showHeader !== false}>
|
|
39
40
|
<div class="flex flex-col gap-2">
|
|
40
|
-
<
|
|
41
|
+
<Heading size="page">Help Center</Heading>
|
|
41
42
|
<p class="text-sm text-muted-foreground">
|
|
42
43
|
Keyboard shortcuts and resources for {props.appName}.
|
|
43
44
|
</p>
|
|
@@ -2,6 +2,7 @@ import type { ComponentProps, JSX } from 'solid-js'
|
|
|
2
2
|
import { createUniqueId, Show, splitProps } from 'solid-js'
|
|
3
3
|
import { createFormFieldContext, FormFieldContext } from '../../../lib/form-field'
|
|
4
4
|
import { cn } from '../../../lib/utils'
|
|
5
|
+
import { Heading } from '../../ui/typography'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* SettingsSection and SettingsRow.
|
|
@@ -43,7 +44,9 @@ export function SettingsSection(
|
|
|
43
44
|
>
|
|
44
45
|
<div class="flex items-start justify-between gap-4">
|
|
45
46
|
<div class="flex min-w-0 flex-col gap-0.5">
|
|
46
|
-
<
|
|
47
|
+
<Heading as="h2" size="card">
|
|
48
|
+
{local.title}
|
|
49
|
+
</Heading>
|
|
47
50
|
<Show when={local.description}>
|
|
48
51
|
<p class="max-w-prose text-sm text-muted-foreground text-pretty">{local.description}</p>
|
|
49
52
|
</Show>
|
|
@@ -3,6 +3,7 @@ import type { ComponentProps, JSX } from 'solid-js'
|
|
|
3
3
|
import { Show, splitProps } from 'solid-js'
|
|
4
4
|
import { Dynamic } from 'solid-js/web'
|
|
5
5
|
import { cn } from '../../../lib/utils'
|
|
6
|
+
import { Heading, Text } from '../../ui/typography'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Stat.
|
|
@@ -53,9 +54,13 @@ export function Stat(props: StatProps) {
|
|
|
53
54
|
>
|
|
54
55
|
<div class="text-muted-foreground truncate text-xs font-medium">{local.label}</div>
|
|
55
56
|
<div class="flex items-baseline gap-1">
|
|
56
|
-
<span
|
|
57
|
+
<Heading as="span" size="page" numeric>
|
|
58
|
+
{local.value}
|
|
59
|
+
</Heading>
|
|
57
60
|
<Show when={local.unit}>
|
|
58
|
-
<
|
|
61
|
+
<Text variant="caption" tone="muted">
|
|
62
|
+
{local.unit}
|
|
63
|
+
</Text>
|
|
59
64
|
</Show>
|
|
60
65
|
</div>
|
|
61
66
|
<Show when={local.delta}>
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from '../../ui/dialog'
|
|
34
34
|
import { createDialogFocusRestoration } from '../../ui/dialog/dialog'
|
|
35
35
|
import { Progress } from '../../ui/progress'
|
|
36
|
+
import { Heading } from '../../ui/typography'
|
|
36
37
|
import { cn } from '../../../lib/utils'
|
|
37
38
|
import { formatBytes, formatReleaseDate, plainTextFromMarkdown } from '../../../lib/version-notes'
|
|
38
39
|
|
|
@@ -590,9 +591,9 @@ export function UpdateDialog(props: UpdateDialogProps) {
|
|
|
590
591
|
<p class="text-2xs font-semibold tracking-widest text-muted-foreground uppercase">
|
|
591
592
|
Installed version
|
|
592
593
|
</p>
|
|
593
|
-
<p
|
|
594
|
+
<Heading as="p" size="page" tone="foreground">
|
|
594
595
|
v{state()?.currentVersion || local.fallbackVersion || '0.1.0'}
|
|
595
|
-
</
|
|
596
|
+
</Heading>
|
|
596
597
|
<p class="text-sm text-muted-foreground">
|
|
597
598
|
<Show
|
|
598
599
|
when={isCurrent()}
|
|
@@ -618,19 +619,30 @@ export function UpdateDialog(props: UpdateDialogProps) {
|
|
|
618
619
|
</Show>
|
|
619
620
|
</p>
|
|
620
621
|
</div>
|
|
621
|
-
<
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
<
|
|
622
|
+
<div class="flex flex-col items-end gap-2">
|
|
623
|
+
<ActionButton
|
|
624
|
+
type="button"
|
|
625
|
+
variant="outline"
|
|
626
|
+
size="sm"
|
|
627
|
+
tooltip="Check the release channel for the latest signed app version."
|
|
628
|
+
disabled={!desktop() || working()}
|
|
629
|
+
onClick={() => void check()}
|
|
630
|
+
>
|
|
631
|
+
<Show when={working()} fallback={<RefreshCw aria-hidden="true" />}>
|
|
632
|
+
<LoaderCircle class="animate-spin" aria-hidden="true" />
|
|
633
|
+
</Show>
|
|
634
|
+
{checkFailed() ? 'Retry update check' : 'Check latest version'}
|
|
635
|
+
</ActionButton>
|
|
636
|
+
{/* The up-to-date confirmation reads as the button's outcome,
|
|
637
|
+
so it sits directly beneath it rather than floating as a
|
|
638
|
+
full-width row between sections. */}
|
|
639
|
+
<Show when={isCurrent()}>
|
|
640
|
+
<p class="text-foreground flex items-center gap-2 text-sm" role="status">
|
|
641
|
+
<Check class="size-4 text-success" aria-hidden="true" />
|
|
642
|
+
{appName()} is up to date.
|
|
643
|
+
</p>
|
|
631
644
|
</Show>
|
|
632
|
-
|
|
633
|
-
</ActionButton>
|
|
645
|
+
</div>
|
|
634
646
|
</div>
|
|
635
647
|
</section>
|
|
636
648
|
|
|
@@ -729,13 +741,6 @@ export function UpdateDialog(props: UpdateDialogProps) {
|
|
|
729
741
|
</section>
|
|
730
742
|
</Show>
|
|
731
743
|
|
|
732
|
-
<Show when={isCurrent()}>
|
|
733
|
-
<p class="text-foreground flex items-center gap-2 text-sm" role="status">
|
|
734
|
-
<Check class="size-4 text-success" aria-hidden="true" />
|
|
735
|
-
{appName()} is up to date.
|
|
736
|
-
</p>
|
|
737
|
-
</Show>
|
|
738
|
-
|
|
739
744
|
<Show when={state()?.phase === 'installed'}>
|
|
740
745
|
<p class="text-foreground flex items-center gap-2 text-sm" role="status">
|
|
741
746
|
<Check class="size-4 text-success" aria-hidden="true" />
|
|
@@ -780,9 +785,16 @@ export function UpdateDialog(props: UpdateDialogProps) {
|
|
|
780
785
|
|
|
781
786
|
<Show when={changelog()}>
|
|
782
787
|
<div class="flex flex-col gap-2">
|
|
783
|
-
<
|
|
784
|
-
|
|
785
|
-
|
|
788
|
+
<div class="flex items-center gap-2">
|
|
789
|
+
<h2 id="update-changelog" class="text-sm font-semibold text-foreground">
|
|
790
|
+
Installed changelog
|
|
791
|
+
</h2>
|
|
792
|
+
{/* The version pill identifies which build's history this is —
|
|
793
|
+
the same treatment the available-update heading carries. */}
|
|
794
|
+
<Badge variant="subtle" size="sm">
|
|
795
|
+
v{state()?.currentVersion || local.fallbackVersion || '0.1.0'}
|
|
796
|
+
</Badge>
|
|
797
|
+
</div>
|
|
786
798
|
<p class="text-xs text-muted-foreground">
|
|
787
799
|
All versions and updates included with this installation.
|
|
788
800
|
</p>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ComponentProps, JSX } from 'solid-js'
|
|
2
2
|
import { Show, splitProps } from 'solid-js'
|
|
3
3
|
import { cn } from '../../../lib/utils'
|
|
4
|
+
import { Heading, headingVariants } from '../../ui/typography'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* PageHeader.
|
|
@@ -44,7 +45,7 @@ export function PageHeaderTitle(props: ComponentProps<'h1'>) {
|
|
|
44
45
|
return (
|
|
45
46
|
<h1
|
|
46
47
|
data-slot="page-header-title"
|
|
47
|
-
class={cn(
|
|
48
|
+
class={cn(headingVariants({ size: 'page' }), local.class)}
|
|
48
49
|
{...rest}
|
|
49
50
|
/>
|
|
50
51
|
)
|
|
@@ -92,7 +93,7 @@ export function PageSection(
|
|
|
92
93
|
<Show when={local.title}>
|
|
93
94
|
<div class="flex items-baseline justify-between gap-3">
|
|
94
95
|
<div class="flex min-w-0 flex-col gap-0.5">
|
|
95
|
-
<
|
|
96
|
+
<Heading size="section">{local.title}</Heading>
|
|
96
97
|
<Show when={local.description}>
|
|
97
98
|
<p class="max-w-prose text-sm text-muted-foreground text-pretty">
|
|
98
99
|
{local.description}
|
|
@@ -7,6 +7,7 @@ import { Button } from '../ui/button/button'
|
|
|
7
7
|
import { RadioGroup, RadioGroupItem } from '../ui/radio-group/radio-group'
|
|
8
8
|
import { ThemePicker } from './theme-picker'
|
|
9
9
|
import { useTheme } from './theme-provider'
|
|
10
|
+
import { Heading } from '../ui/typography'
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* AppearancePanel.
|
|
@@ -43,7 +44,9 @@ export function AppearancePanel(props: AppearancePanelProps) {
|
|
|
43
44
|
{/* --- 1. Appearance ------------------------------------------------- */}
|
|
44
45
|
<section class="flex flex-col gap-3">
|
|
45
46
|
<header class="flex flex-col gap-0.5">
|
|
46
|
-
<
|
|
47
|
+
<Heading as="h2" size="card">
|
|
48
|
+
Appearance
|
|
49
|
+
</Heading>
|
|
47
50
|
<p class="max-w-prose text-sm text-muted-foreground">
|
|
48
51
|
Follow the system, or pin one. The theme below is chosen per appearance, so switching at
|
|
49
52
|
sunset does not make you choose again.
|
|
@@ -87,7 +90,9 @@ export function AppearancePanel(props: AppearancePanelProps) {
|
|
|
87
90
|
{/* --- 3. Accent ------------------------------------------------------ */}
|
|
88
91
|
<section class="flex flex-col gap-3">
|
|
89
92
|
<header class="flex flex-col gap-0.5">
|
|
90
|
-
<
|
|
93
|
+
<Heading as="h2" size="card">
|
|
94
|
+
Accent
|
|
95
|
+
</Heading>
|
|
91
96
|
<p class="max-w-prose text-sm text-muted-foreground">
|
|
92
97
|
Colours the interactive roles — the primary button, the focus ring, a selected row — on
|
|
93
98
|
top of the theme above. Every preset is measured against the surface it lands on, so
|
|
@@ -130,7 +135,9 @@ export function AppearancePanel(props: AppearancePanelProps) {
|
|
|
130
135
|
{/* --- 4. Font -------------------------------------------------------- */}
|
|
131
136
|
<section class="flex flex-col gap-3">
|
|
132
137
|
<header class="flex flex-col gap-0.5">
|
|
133
|
-
<
|
|
138
|
+
<Heading as="h2" size="card">
|
|
139
|
+
Typeface
|
|
140
|
+
</Heading>
|
|
134
141
|
<p class="max-w-prose text-sm text-muted-foreground">
|
|
135
142
|
The interface face. Every option is self-hosted, so nothing is fetched at runtime and
|
|
136
143
|
the choice survives going offline.
|
|
@@ -166,7 +173,9 @@ function ThemeSection(props: {
|
|
|
166
173
|
return (
|
|
167
174
|
<section class="flex flex-col gap-3">
|
|
168
175
|
<header class="flex flex-col gap-0.5">
|
|
169
|
-
<
|
|
176
|
+
<Heading as="h2" size="card">
|
|
177
|
+
{props.title}
|
|
178
|
+
</Heading>
|
|
170
179
|
<p class="max-w-prose text-sm text-muted-foreground">{props.description}</p>
|
|
171
180
|
</header>
|
|
172
181
|
<ThemePicker
|
|
@@ -7,6 +7,7 @@ import type { ComponentProps } from 'solid-js'
|
|
|
7
7
|
import { createEffect, createSignal, splitProps } from 'solid-js'
|
|
8
8
|
import { overlayMotion, overlayPositioner, overlayScrim, overlaySurface } from '../../../lib/overlay'
|
|
9
9
|
import { cn } from '../../../lib/utils'
|
|
10
|
+
import { headingVariants } from '../typography'
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* AlertDialog.
|
|
@@ -117,7 +118,7 @@ export function AlertDialogTitle(props: ComponentProps<typeof KobalteAlertDialog
|
|
|
117
118
|
const [local, rest] = splitProps(props, ['class'])
|
|
118
119
|
return (
|
|
119
120
|
<KobalteAlertDialog.Title
|
|
120
|
-
class={cn('
|
|
121
|
+
class={cn(headingVariants({ size: 'card', leading: 'none' }), local.class)}
|
|
121
122
|
{...rest}
|
|
122
123
|
/>
|
|
123
124
|
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ComponentProps, JSX } from 'solid-js'
|
|
2
2
|
import { splitProps } from 'solid-js'
|
|
3
3
|
import { cn } from '../../../lib/utils'
|
|
4
|
+
import { headingVariants } from '../typography'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Card.
|
|
@@ -41,7 +42,7 @@ export function CardTitle(props: ComponentProps<'div'>) {
|
|
|
41
42
|
return (
|
|
42
43
|
<div
|
|
43
44
|
data-slot="card-title"
|
|
44
|
-
class={cn('
|
|
45
|
+
class={cn(headingVariants({ size: 'card', leading: 'none' }), local.class)}
|
|
45
46
|
{...rest}
|
|
46
47
|
/>
|
|
47
48
|
)
|
|
@@ -45,7 +45,30 @@ const furniture = {
|
|
|
45
45
|
*/
|
|
46
46
|
export type ChartScaleShape = 'cartesian' | 'radial' | 'none'
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The chart's type: the UI face from the font axis and a rung of the type scale,
|
|
50
|
+
* declared as tokens like the colours.
|
|
51
|
+
*
|
|
52
|
+
* Chart.js does not inherit the page's font — it paints in its own default
|
|
53
|
+
* family — so every text a chart draws names `--font-sans` explicitly, and the
|
|
54
|
+
* chart follows `data-font` the same way it follows `.dark`. Everything is
|
|
55
|
+
* `--text-2xs`, the rung `ChartLegend` and the frame's metadata already use, so
|
|
56
|
+
* a canvas legend and an HTML one beside it are the same size.
|
|
57
|
+
*
|
|
58
|
+
* Chart.js types `size` as a number of pixels. The token is a `rem` length, so
|
|
59
|
+
* it is written as `var(--text-2xs)` here and the component resolves it to
|
|
60
|
+
* pixels with the colours (see `resolveCssVariables` and `chart.tsx`); the cast
|
|
61
|
+
* is that declaration, not a number.
|
|
62
|
+
*/
|
|
63
|
+
function chartFont(weight?: number) {
|
|
64
|
+
return {
|
|
65
|
+
family: 'var(--font-sans)',
|
|
66
|
+
size: 'var(--text-2xs)' as unknown as number,
|
|
67
|
+
...(weight === undefined ? {} : { weight }),
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const tickFont = chartFont()
|
|
49
72
|
|
|
50
73
|
function scalesFor(shape: ChartScaleShape): ChartOptions['scales'] {
|
|
51
74
|
if (shape === 'cartesian') {
|
|
@@ -140,7 +163,7 @@ export function chartOptions(
|
|
|
140
163
|
boxHeight: 8,
|
|
141
164
|
usePointStyle: true,
|
|
142
165
|
pointStyle: 'circle',
|
|
143
|
-
font:
|
|
166
|
+
font: chartFont(),
|
|
144
167
|
},
|
|
145
168
|
},
|
|
146
169
|
tooltip: {
|
|
@@ -155,8 +178,9 @@ export function chartOptions(
|
|
|
155
178
|
boxWidth: 8,
|
|
156
179
|
boxHeight: 8,
|
|
157
180
|
usePointStyle: true,
|
|
158
|
-
titleFont:
|
|
159
|
-
bodyFont:
|
|
181
|
+
titleFont: chartFont(600),
|
|
182
|
+
bodyFont: chartFont(),
|
|
183
|
+
footerFont: chartFont(),
|
|
160
184
|
},
|
|
161
185
|
},
|
|
162
186
|
scales: scalesFor(shape),
|
|
@@ -169,17 +193,21 @@ const cssVariable = /^\s*var\(\s*(--[\w-]+)\s*(?:,\s*(.*?))?\s*\)\s*$/
|
|
|
169
193
|
|
|
170
194
|
/**
|
|
171
195
|
* Replace every `var(--token)` string in `value` — options, datasets, nested
|
|
172
|
-
* arrays — with what `read` returns for the token
|
|
196
|
+
* arrays — with what `read` returns for the token, which may be a number (a
|
|
197
|
+
* length token read as pixels). A token `read` cannot
|
|
173
198
|
* resolve falls back to the `var()`'s own fallback, then to the string as
|
|
174
199
|
* written. Functions and class instances pass through untouched, so scriptable
|
|
175
200
|
* options and gradients keep working.
|
|
176
201
|
*/
|
|
177
|
-
export function resolveCssVariables<T>(
|
|
202
|
+
export function resolveCssVariables<T>(
|
|
203
|
+
value: T,
|
|
204
|
+
read: (name: string) => string | number | undefined
|
|
205
|
+
): T {
|
|
178
206
|
if (typeof value === 'string') {
|
|
179
207
|
const match = cssVariable.exec(value)
|
|
180
208
|
if (!match) return value
|
|
181
209
|
const resolved = read(match[1]!)
|
|
182
|
-
if (resolved) return resolved as T
|
|
210
|
+
if (resolved !== undefined && resolved !== '') return resolved as T
|
|
183
211
|
return (match[2] ? resolveCssVariables(match[2], read) : value) as T
|
|
184
212
|
}
|
|
185
213
|
if (Array.isArray(value)) {
|