diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 55c39e35..a7578401 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -1111,5 +1111,18 @@ "validation_max_items": "Choose at most {count}", "validation_email": "Enter a valid email address", "validation_url": "Enter a valid URL", - "validation_number": "Enter a number" + "validation_number": "Enter a number", + "command_menu": "Command menu", + "search_or_jump_to": "Search or jump to…", + "palette_recent": "Recent", + "palette_actions": "Actions", + "palette_navigation": "Navigation", + "palette_settings": "Settings", + "palette_no_results": "No results for “{query}”", + "palette_searching": "Searching…", + "palette_search_failed": "Couldn’t search users and apps.", + "palette_hint_navigate": "to move", + "palette_hint_open": "to open", + "palette_hint_close": "to close", + "hide_advanced_settings": "Hide advanced settings" } diff --git a/frontend/src/app.css b/frontend/src/app.css index 4ff74c06..cdfd1443 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -455,6 +455,39 @@ html.theme-switching *::after { } } +/* A link inside a sentence stands out by contrast and weight rather than a permanent underline, which appears only on hover */ +@utility inline-link { + color: var(--fg); + font-weight: 500; + text-underline-offset: 3px; + text-decoration-line: underline; + text-decoration-thickness: 1px; + text-decoration-color: transparent; + transition: text-decoration-color var(--dur-fast) var(--ease-out); + + &:hover { + text-decoration-color: color-mix(in srgb, currentColor 40%, transparent); + } +} + +/* A key in a shortcut hint, in the palette footer and on its trigger */ +@utility keycap { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 18px; + height: 18px; + padding-inline: 4px; + border-radius: var(--radius-xs); + background: var(--fill-muted); + box-shadow: inset 0 0 0 1px var(--border); + font-family: var(--font-sans); + font-size: 11px; + line-height: 14px; + font-weight: 500; + color: var(--fg-muted); +} + /* Compositor-only motion; Tailwind 4 writes scale and translate as their own properties, so they are listed next to transform */ @utility transition-motion { transition-property: opacity, transform, translate, scale; diff --git a/frontend/src/lib/components/shell/account-menu.svelte b/frontend/src/lib/components/shell/account-menu.svelte index 23e9d828..d0f1584f 100644 --- a/frontend/src/lib/components/shell/account-menu.svelte +++ b/frontend/src/lib/components/shell/account-menu.svelte @@ -4,10 +4,10 @@ import * as DropdownMenu from '#lib/components/ui/dropdown-menu/index.ts'; import * as Tooltip from '#lib/components/ui/tooltip/index.ts'; import { m } from '#lib/paraglide/messages.js'; - import WebAuthnService from '#lib/services/webauthn-service.ts'; - import unsavedChangesStore from '#lib/stores/unsaved-changes-store.svelte.ts'; import userStore from '#lib/stores/user-store.ts'; import { cachedProfilePicture } from '#lib/utils/cached-image-util.ts'; + import { setModeInstantly } from '#lib/utils/color-theme-util.ts'; + import { signOut } from '#lib/utils/sign-out-util.ts'; import { cn } from '#lib/utils/style.ts'; import { IdCard, LogOut, SunMoon } from '@lucide/svelte'; import { userPrefersMode } from 'mode-watcher'; @@ -21,19 +21,10 @@ version?: string; } = $props(); - const webauthnService = new WebAuthnService(); let open = $state(false); + let jumping = $state(false); const appearanceLabels = { light: m.light(), dark: m.dark(), system: m.system() }; - - async function signOut() { - if (!unsavedChangesStore.hasChanges) { - await webauthnService.logout(); - } - - // With unsaved changes the bar blocks this navigation and shakes instead - goto('/login'); - } {#snippet appearanceOptions()} diff --git a/frontend/src/lib/components/shell/app-sidebar.svelte b/frontend/src/lib/components/shell/app-sidebar.svelte index 34dfeb2a..d14d3315 100644 --- a/frontend/src/lib/components/shell/app-sidebar.svelte +++ b/frontend/src/lib/components/shell/app-sidebar.svelte @@ -4,9 +4,11 @@ import * as Tooltip from '#lib/components/ui/tooltip/index.ts'; import { m } from '#lib/paraglide/messages.js'; import appConfigStore from '#lib/stores/application-configuration-store.ts'; + import { commandPalette } from '#lib/stores/command-palette-store.svelte.ts'; import type { AppVersionInformation } from '#lib/types/application-configuration.type.ts'; + import { modKey } from '#lib/utils/keyboard-util.ts'; import { cn } from '#lib/utils/style.ts'; - import { CircleChevronUp, PanelLeftClose, PanelLeftOpen } from '@lucide/svelte'; + import { CircleChevronUp, PanelLeftClose, PanelLeftOpen, Search } from '@lucide/svelte'; import AccountMenu from './account-menu.svelte'; import { activeHref, type NavGroup } from './nav-items.ts'; @@ -84,6 +86,41 @@ + + + + {#snippet child({ props })} + + {/snippet} + + + {m.search_or_jump_to()}{modKey}K + + +