refactor: restyle command palette via tokens

This commit is contained in:
Shantur Rathore
2025-10-28 20:06:38 +00:00
parent a01b9b79ac
commit 176a227103
5 changed files with 114 additions and 59 deletions

View File

@@ -126,18 +126,18 @@ const CommandPalette: Component<CommandPaletteProps> = (props) => {
return ( return (
<Dialog open={props.open} onOpenChange={(open) => !open && props.onClose()}> <Dialog open={props.open} onOpenChange={(open) => !open && props.onClose()}>
<Dialog.Portal> <Dialog.Portal>
<Dialog.Overlay class="fixed inset-0 bg-black/50 z-50" /> <Dialog.Overlay class="modal-overlay" />
<div class="fixed inset-0 z-50 flex items-start justify-center pt-[20vh]"> <div class="fixed inset-0 z-50 flex items-start justify-center pt-[20vh]">
<Dialog.Content <Dialog.Content
class="bg-white dark:bg-gray-800 rounded-lg shadow-2xl w-full max-w-2xl max-h-[60vh] flex flex-col" class="modal-surface w-full max-w-2xl max-h-[60vh]"
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
> >
<Dialog.Title class="sr-only">Command Palette</Dialog.Title> <Dialog.Title class="sr-only">Command Palette</Dialog.Title>
<Dialog.Description class="sr-only">Search and execute commands</Dialog.Description> <Dialog.Description class="sr-only">Search and execute commands</Dialog.Description>
<div class="p-4 border-b border-gray-200 dark:border-gray-700"> <div class="modal-search-container">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5 modal-search-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path <path
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
@@ -154,15 +154,15 @@ const CommandPalette: Component<CommandPaletteProps> = (props) => {
setSelectedIndex(0) setSelectedIndex(0)
}} }}
placeholder="Type a command or search..." placeholder="Type a command or search..."
class="flex-1 bg-transparent outline-none text-gray-900 dark:text-gray-100 placeholder-gray-400" class="modal-search-input"
/> />
</div> </div>
</div> </div>
<div ref={listRef} class="flex-1 overflow-y-auto"> <div ref={listRef} class="modal-list-container">
<Show <Show
when={filteredCommands().length > 0} when={filteredCommands().length > 0}
fallback={<div class="p-8 text-center text-gray-500">No commands found for "{query()}"</div>} fallback={<div class="modal-empty-state">No commands found for "{query()}"</div>}
> >
<For each={Array.from(groupedCommands().entries())}> <For each={Array.from(groupedCommands().entries())}>
{([category, commands]) => { {([category, commands]) => {
@@ -174,7 +174,7 @@ const CommandPalette: Component<CommandPaletteProps> = (props) => {
return ( return (
<div class="py-2"> <div class="py-2">
<div class="px-4 py-2 text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide"> <div class="modal-section-header">
{category} {category}
</div> </div>
<For each={commands}> <For each={commands}>
@@ -185,16 +185,16 @@ const CommandPalette: Component<CommandPaletteProps> = (props) => {
type="button" type="button"
data-command-index={commandIndex} data-command-index={commandIndex}
onClick={() => handleCommandClick(command.id)} onClick={() => handleCommandClick(command.id)}
class={`w-full px-4 py-3 flex items-start gap-3 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors cursor-pointer border-none text-left ${ class={`modal-item ${
commandIndex === selectedIndex() ? "bg-blue-50 dark:bg-blue-900/20" : "" commandIndex === selectedIndex() ? "modal-item-highlight" : ""
}`} }`}
onMouseEnter={() => setSelectedIndex(commandIndex)} onMouseEnter={() => setSelectedIndex(commandIndex)}
> >
<div class="flex-1 min-w-0"> <div class="flex-1 min-w-0">
<div class="font-medium text-gray-900 dark:text-gray-100"> <div class="modal-item-label">
{typeof command.label === "function" ? command.label() : command.label} {typeof command.label === "function" ? command.label() : command.label}
</div> </div>
<div class="text-sm text-gray-600 dark:text-gray-400 mt-0.5"> <div class="modal-item-description">
{command.description} {command.description}
</div> </div>
</div> </div>

View File

@@ -219,7 +219,7 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
</div> </div>
</div> </div>
<Show when={focusMode() === "recent" && selectedIndex() === index()}> <Show when={focusMode() === "recent" && selectedIndex() === index()}>
<kbd class="px-1.5 py-0.5 text-xs font-semibold text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded"> <kbd class="kbd">
</kbd> </kbd>
</Show> </Show>
@@ -256,7 +256,7 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
<FolderPlus class="w-4 h-4" /> <FolderPlus class="w-4 h-4" />
<span>{props.isLoading ? "Opening..." : "Browse Folders"}</span> <span>{props.isLoading ? "Opening..." : "Browse Folders"}</span>
</div> </div>
<kbd class="px-1.5 py-0.5 text-xs font-semibold bg-blue-700 border border-blue-500 rounded"> <kbd class="kbd">
Cmd+Enter Cmd+Enter
</kbd> </kbd>
</button> </button>
@@ -303,31 +303,21 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
<div class="flex items-center justify-center flex-wrap gap-3 text-xs text-gray-500 dark:text-gray-400"> <div class="flex items-center justify-center flex-wrap gap-3 text-xs text-gray-500 dark:text-gray-400">
<Show when={folders().length > 0}> <Show when={folders().length > 0}>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded font-mono"> <kbd class="kbd"></kbd>
<kbd class="kbd"></kbd>
</kbd>
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded font-mono">
</kbd>
<span>Navigate</span> <span>Navigate</span>
</div> </div>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded font-mono"> <kbd class="kbd">Enter</kbd>
Enter
</kbd>
<span>Select</span> <span>Select</span>
</div> </div>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded font-mono"> <kbd class="kbd">Del</kbd>
Del
</kbd>
<span>Remove</span> <span>Remove</span>
</div> </div>
</Show> </Show>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded"> <kbd class="kbd">Cmd+Enter</kbd>
Cmd+Enter
</kbd>
<span>Browse</span> <span>Browse</span>
</div> </div>
</div> </div>

View File

@@ -211,7 +211,7 @@ const InstanceWelcomeView: Component<InstanceWelcomeViewProps> = (props) => {
</div> </div>
</div> </div>
<Show when={focusMode() === "sessions" && selectedIndex() === index()}> <Show when={focusMode() === "sessions" && selectedIndex() === index()}>
<kbd class="px-1.5 py-0.5 text-xs font-semibold text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded flex-shrink-0"> <kbd class="kbd flex-shrink-0">
</kbd> </kbd>
</Show> </Show>
@@ -281,7 +281,7 @@ const InstanceWelcomeView: Component<InstanceWelcomeViewProps> = (props) => {
</svg> </svg>
<span>Create Session</span> <span>Create Session</span>
</div> </div>
<kbd class="px-1.5 py-0.5 text-xs font-semibold bg-blue-700 border border-blue-500 rounded flex-shrink-0 dark:bg-blue-600 dark:border-blue-400"> <kbd class="kbd flex-shrink-0">
Cmd+Enter Cmd+Enter
</kbd> </kbd>
</Show> </Show>
@@ -302,42 +302,26 @@ const InstanceWelcomeView: Component<InstanceWelcomeViewProps> = (props) => {
<div class="px-4 py-2 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 flex-shrink-0"> <div class="px-4 py-2 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 flex-shrink-0">
<div class="flex items-center justify-center flex-wrap gap-3 text-xs text-gray-500 dark:text-gray-400"> <div class="flex items-center justify-center flex-wrap gap-3 text-xs text-gray-500 dark:text-gray-400">
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded font-mono text-xs"> <kbd class="kbd"></kbd>
<kbd class="kbd"></kbd>
</kbd>
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded font-mono text-xs">
</kbd>
<span>Navigate</span> <span>Navigate</span>
</div> </div>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded font-mono text-xs"> <kbd class="kbd">PgUp</kbd>
PgUp <kbd class="kbd">PgDn</kbd>
</kbd>
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded font-mono text-xs">
PgDn
</kbd>
<span>Jump</span> <span>Jump</span>
</div> </div>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded font-mono text-xs"> <kbd class="kbd">Home</kbd>
Home <kbd class="kbd">End</kbd>
</kbd>
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded font-mono text-xs">
End
</kbd>
<span>First/Last</span> <span>First/Last</span>
</div> </div>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded font-mono text-xs"> <kbd class="kbd">Enter</kbd>
Enter
</kbd>
<span>Resume</span> <span>Resume</span>
</div> </div>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<kbd class="px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded text-xs"> <kbd class="kbd">Cmd+Enter</kbd>
Cmd+Enter
</kbd>
<span>New Session</span> <span>New Session</span>
</div> </div>
</div> </div>

View File

@@ -36,13 +36,11 @@ const Kbd: Component<KbdProps> = (props) => {
} }
return ( return (
<kbd <kbd class={`kbd ${props.class || ""}`}>
class={`font-mono bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded text-xs inline-flex items-center gap-0.5 ${props.class || ""}`}
>
<For each={parts()}> <For each={parts()}>
{(part, index) => ( {(part, index) => (
<> <>
{index() > 0 && <span class="opacity-50">+</span>} {index() > 0 && <span class="kbd-separator">+</span>}
<span>{part.text}</span> <span>{part.text}</span>
</> </>
)} )}

View File

@@ -1041,3 +1041,86 @@
@apply w-4 h-4 animate-spin; @apply w-4 h-4 animate-spin;
color: var(--accent-primary); color: var(--accent-primary);
} }
/* Modal utilities */
.modal-overlay {
@apply fixed inset-0 z-50;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-surface {
@apply rounded-lg shadow-2xl flex flex-col;
background-color: var(--surface-base);
color: var(--text-primary);
}
.modal-search-container {
@apply p-4 border-b;
border-color: var(--border-base);
}
.modal-search-input {
@apply flex-1 bg-transparent outline-none;
color: var(--text-primary);
}
.modal-search-input::placeholder {
color: var(--text-muted);
}
.modal-search-icon {
color: var(--text-muted);
}
.modal-list-container {
@apply flex-1 overflow-y-auto;
}
.modal-section-header {
@apply px-4 py-2 text-xs font-semibold uppercase tracking-wide;
color: var(--text-muted);
}
.modal-item {
@apply w-full px-4 py-3 flex items-start gap-3 transition-colors cursor-pointer border-none text-left;
color: var(--text-primary);
}
.modal-item:hover {
background-color: var(--surface-hover);
}
.modal-item-highlight {
background-color: rgba(0, 102, 255, 0.1);
}
[data-theme="dark"] .modal-item-highlight {
background-color: rgba(0, 128, 255, 0.2);
}
.modal-item-label {
@apply font-medium;
color: var(--text-primary);
}
.modal-item-description {
@apply text-sm mt-0.5;
color: var(--text-secondary);
}
.modal-empty-state {
@apply p-8 text-center;
color: var(--text-muted);
}
/* Keyboard utilities */
.kbd {
@apply inline-flex items-center gap-0.5 font-mono text-xs px-1.5 py-0.5 rounded;
background-color: var(--surface-secondary);
border: 1px solid var(--border-base);
color: var(--text-primary);
}
.kbd-separator {
@apply opacity-50;
}