From 0e8a4ccfeeaa92fdbd0fe2b8a06b5d169697f8b6 Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Tue, 27 Jan 2026 10:26:14 +0100 Subject: [PATCH] refactor: Components --- .../app/{misc => actions}/ActionButton.svelte | 0 .../CopyToClipboardIcon.svelte | 0 .../KeyboardShortcutInfo.svelte | 0 .../app/{misc => actions}/RemoveButton.svelte | 0 .../src/lib/components/app/actions/index.ts | 16 +- .../app/content/CodeBlockActions.svelte | 54 + .../content/CollapsibleContentBlock.svelte | 14 +- .../app/content/MarkdownContent.svelte | 224 +--- .../src/lib/components/app/content/index.ts | 5 +- .../DialogCodePreview.svelte} | 0 .../src/lib/components/app/dialogs/index.ts | 38 + .../app/{misc => forms}/KeyValuePairs.svelte | 0 .../app/{misc => forms}/SearchInput.svelte | 0 .../src/lib/components/app/forms/index.ts | 30 + .../webui/src/lib/components/app/index.ts | 5 + .../app/misc/BadgeChatStatistic.svelte | 44 - .../lib/components/app/misc/BadgeInfo.svelte | 27 - .../components/app/misc/BadgeModality.svelte | 39 - .../app/misc/CollapsibleContentBlock.svelte | 103 -- .../app/misc/DropdownMenuActions.svelte | 86 -- .../app/misc/DropdownMenuSearchable.svelte | 88 -- .../app/misc/MarkdownContent.svelte | 1148 ----------------- .../app/misc/SyntaxHighlightedCode.svelte | 95 -- .../src/lib/components/app/misc/index.ts | 245 +--- .../navigation/DropdownMenuSearchable.svelte | 74 +- .../lib/components/app/navigation/index.ts | 34 +- 26 files changed, 287 insertions(+), 2082 deletions(-) rename tools/server/webui/src/lib/components/app/{misc => actions}/ActionButton.svelte (100%) rename tools/server/webui/src/lib/components/app/{misc => actions}/CopyToClipboardIcon.svelte (100%) rename tools/server/webui/src/lib/components/app/{misc => actions}/KeyboardShortcutInfo.svelte (100%) rename tools/server/webui/src/lib/components/app/{misc => actions}/RemoveButton.svelte (100%) create mode 100644 tools/server/webui/src/lib/components/app/content/CodeBlockActions.svelte rename tools/server/webui/src/lib/components/app/{misc/CodePreviewDialog.svelte => dialogs/DialogCodePreview.svelte} (100%) rename tools/server/webui/src/lib/components/app/{misc => forms}/KeyValuePairs.svelte (100%) rename tools/server/webui/src/lib/components/app/{misc => forms}/SearchInput.svelte (100%) create mode 100644 tools/server/webui/src/lib/components/app/forms/index.ts delete mode 100644 tools/server/webui/src/lib/components/app/misc/BadgeChatStatistic.svelte delete mode 100644 tools/server/webui/src/lib/components/app/misc/BadgeInfo.svelte delete mode 100644 tools/server/webui/src/lib/components/app/misc/BadgeModality.svelte delete mode 100644 tools/server/webui/src/lib/components/app/misc/CollapsibleContentBlock.svelte delete mode 100644 tools/server/webui/src/lib/components/app/misc/DropdownMenuActions.svelte delete mode 100644 tools/server/webui/src/lib/components/app/misc/DropdownMenuSearchable.svelte delete mode 100644 tools/server/webui/src/lib/components/app/misc/MarkdownContent.svelte delete mode 100644 tools/server/webui/src/lib/components/app/misc/SyntaxHighlightedCode.svelte diff --git a/tools/server/webui/src/lib/components/app/misc/ActionButton.svelte b/tools/server/webui/src/lib/components/app/actions/ActionButton.svelte similarity index 100% rename from tools/server/webui/src/lib/components/app/misc/ActionButton.svelte rename to tools/server/webui/src/lib/components/app/actions/ActionButton.svelte diff --git a/tools/server/webui/src/lib/components/app/misc/CopyToClipboardIcon.svelte b/tools/server/webui/src/lib/components/app/actions/CopyToClipboardIcon.svelte similarity index 100% rename from tools/server/webui/src/lib/components/app/misc/CopyToClipboardIcon.svelte rename to tools/server/webui/src/lib/components/app/actions/CopyToClipboardIcon.svelte diff --git a/tools/server/webui/src/lib/components/app/misc/KeyboardShortcutInfo.svelte b/tools/server/webui/src/lib/components/app/actions/KeyboardShortcutInfo.svelte similarity index 100% rename from tools/server/webui/src/lib/components/app/misc/KeyboardShortcutInfo.svelte rename to tools/server/webui/src/lib/components/app/actions/KeyboardShortcutInfo.svelte diff --git a/tools/server/webui/src/lib/components/app/misc/RemoveButton.svelte b/tools/server/webui/src/lib/components/app/actions/RemoveButton.svelte similarity index 100% rename from tools/server/webui/src/lib/components/app/misc/RemoveButton.svelte rename to tools/server/webui/src/lib/components/app/actions/RemoveButton.svelte diff --git a/tools/server/webui/src/lib/components/app/actions/index.ts b/tools/server/webui/src/lib/components/app/actions/index.ts index 43485c7b7e..e5fc04afc8 100644 --- a/tools/server/webui/src/lib/components/app/actions/index.ts +++ b/tools/server/webui/src/lib/components/app/actions/index.ts @@ -6,14 +6,14 @@ * */ -/** Styled icon button for action triggers with tooltip. */ -export { default as ActionIcon } from './ActionIcon.svelte'; +/** Styled button for action triggers with icon support. */ +export { default as ActionButton } from './ActionButton.svelte'; -/** Code block actions component (copy, preview). */ -export { default as ActionIconsCodeBlock } from './ActionIconsCodeBlock.svelte'; +/** Copy-to-clipboard button with success feedback. */ +export { default as CopyToClipboardIcon } from './CopyToClipboardIcon.svelte'; -/** Copy-to-clipboard icon button with click handler. */ -export { default as ActionIconCopyToClipboard } from './ActionIconCopyToClipboard.svelte'; +/** Remove/delete button with X icon. */ +export { default as RemoveButton } from './RemoveButton.svelte'; -/** Remove/delete icon button with X icon. */ -export { default as ActionIconRemove } from './ActionIconRemove.svelte'; +/** Display for keyboard shortcut hints (e.g., "⌘ + Enter"). */ +export { default as KeyboardShortcutInfo } from './KeyboardShortcutInfo.svelte'; diff --git a/tools/server/webui/src/lib/components/app/content/CodeBlockActions.svelte b/tools/server/webui/src/lib/components/app/content/CodeBlockActions.svelte new file mode 100644 index 0000000000..2995853a93 --- /dev/null +++ b/tools/server/webui/src/lib/components/app/content/CodeBlockActions.svelte @@ -0,0 +1,54 @@ + + +
+ + {#if showPreview} + + {/if} +
diff --git a/tools/server/webui/src/lib/components/app/content/CollapsibleContentBlock.svelte b/tools/server/webui/src/lib/components/app/content/CollapsibleContentBlock.svelte index 082738da57..9f01cb6851 100644 --- a/tools/server/webui/src/lib/components/app/content/CollapsibleContentBlock.svelte +++ b/tools/server/webui/src/lib/components/app/content/CollapsibleContentBlock.svelte @@ -1,4 +1,13 @@ - -{#if tooltipLabel} - - - - {#snippet icon()} - - {/snippet} - - {value} - - - -

{tooltipLabel}

-
-
-{:else} - - {#snippet icon()} - - {/snippet} - - {value} - -{/if} diff --git a/tools/server/webui/src/lib/components/app/misc/BadgeInfo.svelte b/tools/server/webui/src/lib/components/app/misc/BadgeInfo.svelte deleted file mode 100644 index c70af6f423..0000000000 --- a/tools/server/webui/src/lib/components/app/misc/BadgeInfo.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/tools/server/webui/src/lib/components/app/misc/BadgeModality.svelte b/tools/server/webui/src/lib/components/app/misc/BadgeModality.svelte deleted file mode 100644 index a0d5e863c2..0000000000 --- a/tools/server/webui/src/lib/components/app/misc/BadgeModality.svelte +++ /dev/null @@ -1,39 +0,0 @@ - - -{#each displayableModalities as modality, index (index)} - {@const IconComponent = MODALITY_ICONS[modality]} - {@const label = MODALITY_LABELS[modality]} - - - {#if IconComponent} - - {/if} - - {label} - -{/each} diff --git a/tools/server/webui/src/lib/components/app/misc/CollapsibleContentBlock.svelte b/tools/server/webui/src/lib/components/app/misc/CollapsibleContentBlock.svelte deleted file mode 100644 index 9f01cb6851..0000000000 --- a/tools/server/webui/src/lib/components/app/misc/CollapsibleContentBlock.svelte +++ /dev/null @@ -1,103 +0,0 @@ - - - { - open = value; - onToggle?.(); - }} - class={className} -> - - -
- {#if Icon} - - {/if} - {title} - {#if subtitle} - {subtitle} - {/if} -
- -
- - Toggle content -
-
- - -
- {@render children()} -
-
-
-
diff --git a/tools/server/webui/src/lib/components/app/misc/DropdownMenuActions.svelte b/tools/server/webui/src/lib/components/app/misc/DropdownMenuActions.svelte deleted file mode 100644 index 83d856d10e..0000000000 --- a/tools/server/webui/src/lib/components/app/misc/DropdownMenuActions.svelte +++ /dev/null @@ -1,86 +0,0 @@ - - - - e.stopPropagation()} - > - {#if triggerTooltip} - - - {@render iconComponent(triggerIcon, 'h-3 w-3')} - {triggerTooltip} - - -

{triggerTooltip}

-
-
- {:else} - {@render iconComponent(triggerIcon, 'h-3 w-3')} - {/if} -
- - - {#each actions as action, index (action.label)} - {#if action.separator && index > 0} - - {/if} - - -
- {@render iconComponent( - action.icon, - `h-4 w-4 ${action.variant === 'destructive' ? 'text-destructive' : ''}` - )} - {action.label} -
- - {#if action.shortcut} - - {/if} -
- {/each} -
-
- -{#snippet iconComponent(IconComponent: Component, className: string)} - -{/snippet} diff --git a/tools/server/webui/src/lib/components/app/misc/DropdownMenuSearchable.svelte b/tools/server/webui/src/lib/components/app/misc/DropdownMenuSearchable.svelte deleted file mode 100644 index 21ba04cf66..0000000000 --- a/tools/server/webui/src/lib/components/app/misc/DropdownMenuSearchable.svelte +++ /dev/null @@ -1,88 +0,0 @@ - - - - { - e.preventDefault(); - e.stopPropagation(); - }} - > - {@render trigger()} - - - -
- -
- -
- {@render children()} - - {#if isEmpty} -
{emptyMessage}
- {/if} -
- - {#if footer} - - - {@render footer()} - {/if} -
-
diff --git a/tools/server/webui/src/lib/components/app/misc/MarkdownContent.svelte b/tools/server/webui/src/lib/components/app/misc/MarkdownContent.svelte deleted file mode 100644 index 4c93cde2d4..0000000000 --- a/tools/server/webui/src/lib/components/app/misc/MarkdownContent.svelte +++ /dev/null @@ -1,1148 +0,0 @@ - - -
- {#each renderedBlocks as block (block.id)} -
- - {@html block.html} -
- {/each} - - {#if unstableBlockHtml} -
- - {@html unstableBlockHtml} -
- {/if} - - {#if incompleteCodeBlock} -
-
- {incompleteCodeBlock.language || 'text'} -
- - {#if incompleteCodeBlock.language?.toLowerCase() === 'html'} - - {/if} -
-
-
streamingAutoScroll.handleScroll()} - > -
{@html highlightCode(
-							incompleteCodeBlock.code,
-							incompleteCodeBlock.language || 'text'
-						)}
-
-
- {/if} -
- - - - diff --git a/tools/server/webui/src/lib/components/app/misc/SyntaxHighlightedCode.svelte b/tools/server/webui/src/lib/components/app/misc/SyntaxHighlightedCode.svelte deleted file mode 100644 index 625fdc7b1b..0000000000 --- a/tools/server/webui/src/lib/components/app/misc/SyntaxHighlightedCode.svelte +++ /dev/null @@ -1,95 +0,0 @@ - - -
- -
{@html highlightedHtml}
-
- - diff --git a/tools/server/webui/src/lib/components/app/misc/index.ts b/tools/server/webui/src/lib/components/app/misc/index.ts index 39572300cb..dc61b519bb 100644 --- a/tools/server/webui/src/lib/components/app/misc/index.ts +++ b/tools/server/webui/src/lib/components/app/misc/index.ts @@ -2,113 +2,10 @@ * * MISC * - * Reusable utility components used across the application. - * Includes content rendering, UI primitives, and helper components. + * Miscellaneous utility components. * */ -/** - * - * CONTENT RENDERING - * - * Components for rendering rich content: markdown, code, and previews. - * - */ - -/** - * **MarkdownContent** - Rich markdown renderer - * - * Renders markdown content with syntax highlighting, LaTeX math, - * tables, links, and code blocks. Optimized for streaming with - * incremental block-based rendering. - * - * **Features:** - * - GFM (GitHub Flavored Markdown): tables, task lists, strikethrough - * - LaTeX math via KaTeX (`$inline$` and `$$block$$`) - * - Syntax highlighting (highlight.js) with language detection - * - Code copy buttons with click feedback - * - External links open in new tab with security attrs - * - Image attachment resolution from message extras - * - Dark/light theme support (auto-switching) - * - Streaming-optimized incremental rendering - * - Code preview dialog for large blocks - * - * @example - * ```svelte - * - * ``` - */ -export { default as MarkdownContent } from './MarkdownContent.svelte'; - -/** - * **SyntaxHighlightedCode** - Code syntax highlighting - * - * Renders code with syntax highlighting using highlight.js. - * Supports theme switching and scrollable containers. - * - * **Features:** - * - Auto language detection with fallback - * - Dark/light theme auto-switching - * - Scrollable container with configurable max dimensions - * - Monospace font styling - * - Preserves whitespace and formatting - * - * @example - * ```svelte - * - * ``` - */ -export { default as SyntaxHighlightedCode } from './SyntaxHighlightedCode.svelte'; - -/** - * **CodePreviewDialog** - Full-screen code preview - * - * Full-screen dialog for previewing HTML/code in an isolated iframe. - * Used by MarkdownContent for previewing rendered HTML blocks. - * - * **Features:** - * - Full viewport iframe preview - * - Sandboxed execution (allow-scripts only) - * - Close button with mix-blend-difference for visibility - * - Clears content when closed for security - */ -export { default as CodePreviewDialog } from './CodePreviewDialog.svelte'; - -/** - * - * COLLAPSIBLE & EXPANDABLE - * - * Components for showing/hiding content sections. - * - */ - -/** - * **CollapsibleContentBlock** - Expandable content card - * - * Reusable collapsible card with header, icon, and auto-scroll. - * Used for tool calls and reasoning blocks in chat messages. - * - * **Features:** - * - Collapsible content with smooth animation - * - Custom icon and title display - * - Optional subtitle/status text - * - Auto-scroll during streaming (pauses on user scroll) - * - Configurable max height with overflow scroll - * - * @example - * ```svelte - * - * {reasoningContent} - * - * ``` - */ -export { default as CollapsibleContentBlock } from './CollapsibleContentBlock.svelte'; - /** * **TruncatedText** - Text with ellipsis and tooltip * @@ -117,135 +14,6 @@ export { default as CollapsibleContentBlock } from './CollapsibleContentBlock.sv */ export { default as TruncatedText } from './TruncatedText.svelte'; -/** - * - * DROPDOWNS & MENUS - * - * Components for dropdown menus and action selection. - * - */ - -/** - * **DropdownMenuSearchable** - Filterable dropdown menu - * - * Generic dropdown with search input for filtering options. - * Uses Svelte snippets for flexible content rendering. - * - * **Features:** - * - Search/filter input with clear on close - * - Keyboard navigation support - * - Custom trigger, content, and footer via snippets - * - Empty state message - * - Disabled state - * - Configurable alignment and width - * - * @example - * ```svelte - * - * {#snippet trigger()}{/snippet} - * {#snippet children()}{#each items as item}{/each}{/snippet} - * - * ``` - */ -export { default as DropdownMenuSearchable } from './DropdownMenuSearchable.svelte'; - -/** - * **DropdownMenuActions** - Multi-action dropdown menu - * - * Dropdown menu for multiple action options with icons and shortcuts. - * Supports destructive variants and keyboard shortcut hints. - * - * **Features:** - * - Configurable trigger icon with tooltip - * - Action items with icons and labels - * - Destructive variant styling - * - Keyboard shortcut display - * - Separator support between groups - * - * @example - * ```svelte - * - * ``` - */ -export { default as DropdownMenuActions } from './DropdownMenuActions.svelte'; - -/** - * - * BUTTONS & ACTIONS - * - * Small interactive components for user actions. - * - */ - -/** Styled button for action triggers with icon support. */ -export { default as ActionButton } from './ActionButton.svelte'; - -/** Copy-to-clipboard button with success feedback. */ -export { default as CopyToClipboardIcon } from './CopyToClipboardIcon.svelte'; - -/** Remove/delete button with X icon. */ -export { default as RemoveButton } from './RemoveButton.svelte'; - -/** - * - * BADGES & INDICATORS - * - * Small visual indicators for status and metadata. - * - */ - -/** Badge displaying chat statistics (tokens, timing). */ -export { default as BadgeChatStatistic } from './BadgeChatStatistic.svelte'; - -/** Generic info badge with optional tooltip and click handler. */ -export { default as BadgeInfo } from './BadgeInfo.svelte'; - -/** Badge indicating model modality (vision, audio, tools). */ -export { default as BadgeModality } from './BadgeModality.svelte'; - -/** - * - * FORMS & INPUTS - * - * Form-related utility components. - * - */ - -/** - * **SearchInput** - Search field with clear button - * - * Input field optimized for search with clear button and keyboard handling. - * Supports placeholder, autofocus, and change callbacks. - */ -export { default as SearchInput } from './SearchInput.svelte'; - -/** - * **KeyValuePairs** - Editable key-value list - * - * Dynamic list of key-value pairs with add/remove functionality. - * Used for HTTP headers, metadata, and configuration. - * - * **Features:** - * - Add new pairs with button - * - Remove individual pairs - * - Customizable placeholders and labels - * - Empty state message - * - Auto-resize value textarea - */ -export { default as KeyValuePairs } from './KeyValuePairs.svelte'; - /** * **ConversationSelection** - Multi-select conversation picker * @@ -260,14 +28,3 @@ export { default as KeyValuePairs } from './KeyValuePairs.svelte'; * - Mode-specific UI (export vs import) */ export { default as ConversationSelection } from './ConversationSelection.svelte'; - -/** - * - * KEYBOARD & SHORTCUTS - * - * Components for displaying keyboard shortcuts. - * - */ - -/** Display for keyboard shortcut hints (e.g., "⌘ + Enter"). */ -export { default as KeyboardShortcutInfo } from './KeyboardShortcutInfo.svelte'; diff --git a/tools/server/webui/src/lib/components/app/navigation/DropdownMenuSearchable.svelte b/tools/server/webui/src/lib/components/app/navigation/DropdownMenuSearchable.svelte index 3bd68d3bd6..21ba04cf66 100644 --- a/tools/server/webui/src/lib/components/app/navigation/DropdownMenuSearchable.svelte +++ b/tools/server/webui/src/lib/components/app/navigation/DropdownMenuSearchable.svelte @@ -1,50 +1,88 @@ -
- -
+ + { + e.preventDefault(); + e.stopPropagation(); + }} + > + {@render trigger()} + -
- {@render children()} + +
+ +
- {#if isEmpty} -
{emptyMessage}
- {/if} -
+
+ {@render children()} -{#if footer} - + {#if isEmpty} +
{emptyMessage}
+ {/if} +
- {@render footer()} -{/if} + {#if footer} + + + {@render footer()} + {/if} + +
diff --git a/tools/server/webui/src/lib/components/app/navigation/index.ts b/tools/server/webui/src/lib/components/app/navigation/index.ts index 051491b866..6a8a99c627 100644 --- a/tools/server/webui/src/lib/components/app/navigation/index.ts +++ b/tools/server/webui/src/lib/components/app/navigation/index.ts @@ -7,32 +7,30 @@ */ /** - * **DropdownMenuSearchable** - Searchable content for dropdown menus + * **DropdownMenuSearchable** - Filterable dropdown menu * - * Renders a search input with filtered content area, empty state, and optional footer. - * Designed to be injected into any dropdown container (DropdownMenu.Content, - * DropdownMenu.SubContent, etc.) without providing its own Root. + * Generic dropdown with search input for filtering options. + * Uses Svelte snippets for flexible content rendering. * * **Features:** - * - Search/filter input + * - Search/filter input with clear on close * - Keyboard navigation support - * - Custom content and footer via snippets + * - Custom trigger, content, and footer via snippets * - Empty state message + * - Disabled state + * - Configurable alignment and width * * @example * ```svelte - * - * ... - * - * - * {#each items as item}{/each} - * - * - * + * + * {#snippet trigger()}{/snippet} + * {#snippet children()}{#each items as item}{/each}{/snippet} + * * ``` */ export { default as DropdownMenuSearchable } from './DropdownMenuSearchable.svelte';