refactor: Components
This commit is contained in:
parent
b8221e8915
commit
1b7f576baf
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
*
|
||||
* 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';
|
||||
|
||||
/** Display for keyboard shortcut hints (e.g., "⌘ + Enter"). */
|
||||
export { default as KeyboardShortcutInfo } from './KeyboardShortcutInfo.svelte';
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
*
|
||||
* 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';
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<script lang="ts">
|
||||
import { Copy, Eye } from '@lucide/svelte';
|
||||
import { copyCodeToClipboard } from '$lib/utils';
|
||||
|
||||
interface Props {
|
||||
code: string;
|
||||
language: string;
|
||||
disabled?: boolean;
|
||||
onPreview?: (code: string, language: string) => void;
|
||||
}
|
||||
|
||||
let { code, language, disabled = false, onPreview }: Props = $props();
|
||||
|
||||
const showPreview = $derived(language?.toLowerCase() === 'html');
|
||||
|
||||
function handleCopy() {
|
||||
if (disabled) return;
|
||||
copyCodeToClipboard(code);
|
||||
}
|
||||
|
||||
function handlePreview() {
|
||||
if (disabled) return;
|
||||
onPreview?.(code, language);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="code-block-actions">
|
||||
<button
|
||||
class="copy-code-btn"
|
||||
class:opacity-50={disabled}
|
||||
class:!cursor-not-allowed={disabled}
|
||||
title={disabled ? 'Code incomplete' : 'Copy code'}
|
||||
aria-label="Copy code"
|
||||
aria-disabled={disabled}
|
||||
type="button"
|
||||
onclick={handleCopy}
|
||||
>
|
||||
<Copy size={16} />
|
||||
</button>
|
||||
{#if showPreview}
|
||||
<button
|
||||
class="preview-code-btn"
|
||||
class:opacity-50={disabled}
|
||||
class:!cursor-not-allowed={disabled}
|
||||
title={disabled ? 'Code incomplete' : 'Preview code'}
|
||||
aria-label="Preview code"
|
||||
aria-disabled={disabled}
|
||||
type="button"
|
||||
onclick={handlePreview}
|
||||
>
|
||||
<Eye size={16} />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -26,7 +26,8 @@
|
|||
import githubDarkCss from 'highlight.js/styles/github-dark.css?inline';
|
||||
import githubLightCss from 'highlight.js/styles/github.css?inline';
|
||||
import { mode } from 'mode-watcher';
|
||||
import CodePreviewDialog from './CodePreviewDialog.svelte';
|
||||
import { DialogCodePreview } from '$lib/components/app/dialogs';
|
||||
import CodeBlockActions from './CodeBlockActions.svelte';
|
||||
import { createAutoScrollController } from '$lib/hooks/use-auto-scroll.svelte';
|
||||
import type { DatabaseMessage } from '$lib/types/database';
|
||||
|
||||
|
|
@ -514,58 +515,16 @@
|
|||
<div class="code-block-wrapper streaming-code-block relative">
|
||||
<div class="code-block-header">
|
||||
<span class="code-language">{incompleteCodeBlock.language || 'text'}</span>
|
||||
<div class="code-block-actions">
|
||||
<button
|
||||
class="copy-code-btn"
|
||||
title="Copy code"
|
||||
aria-label="Copy code"
|
||||
type="button"
|
||||
onclick={() => copyCodeToClipboard(incompleteCodeBlock?.code ?? '')}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path
|
||||
d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"
|
||||
/></svg
|
||||
>
|
||||
</button>
|
||||
{#if incompleteCodeBlock.language?.toLowerCase() === 'html'}
|
||||
<button
|
||||
class="preview-code-btn"
|
||||
title="Preview code"
|
||||
aria-label="Preview code"
|
||||
type="button"
|
||||
onclick={() => {
|
||||
previewCode = incompleteCodeBlock?.code ?? '';
|
||||
previewLanguage = incompleteCodeBlock?.language ?? 'html';
|
||||
previewDialogOpen = true;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
><path
|
||||
d="M2.062 12.345a1 1 0 0 1 0-.69C3.5 7.73 7.36 5 12 5s8.5 2.73 9.938 6.655a1 1 0 0 1 0 .69C20.5 16.27 16.64 19 12 19s-8.5-2.73-9.938-6.655"
|
||||
/><circle cx="12" cy="12" r="3" /></svg
|
||||
>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<CodeBlockActions
|
||||
code={incompleteCodeBlock.code}
|
||||
language={incompleteCodeBlock.language || 'text'}
|
||||
disabled={true}
|
||||
onPreview={(code, lang) => {
|
||||
previewCode = code;
|
||||
previewLanguage = lang;
|
||||
previewDialogOpen = true;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
bind:this={streamingCodeScrollContainer}
|
||||
|
|
@ -584,7 +543,7 @@
|
|||
{/if}
|
||||
</div>
|
||||
|
||||
<CodePreviewDialog
|
||||
<DialogCodePreview
|
||||
open={previewDialogOpen}
|
||||
code={previewCode}
|
||||
language={previewLanguage}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
*
|
||||
* 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
|
||||
* <MarkdownContent content={message.content} {message} />
|
||||
* ```
|
||||
*/
|
||||
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
|
||||
* <SyntaxHighlightedCode code={jsonString} language="json" />
|
||||
* ```
|
||||
*/
|
||||
export { default as SyntaxHighlightedCode } from './SyntaxHighlightedCode.svelte';
|
||||
|
||||
/**
|
||||
* **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
|
||||
* <CollapsibleContentBlock
|
||||
* bind:open
|
||||
* icon={BrainIcon}
|
||||
* title="Thinking..."
|
||||
* isStreaming={true}
|
||||
* >
|
||||
* {reasoningContent}
|
||||
* </CollapsibleContentBlock>
|
||||
* ```
|
||||
*/
|
||||
export { default as CollapsibleContentBlock } from './CollapsibleContentBlock.svelte';
|
||||
|
||||
/** Code block actions component (copy, preview). */
|
||||
export { default as CodeBlockActions } from './CodeBlockActions.svelte';
|
||||
|
|
@ -136,6 +136,44 @@ export { default as DialogConfirmation } from './DialogConfirmation.svelte';
|
|||
*/
|
||||
export { default as DialogConversationTitleUpdate } from './DialogConversationTitleUpdate.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* CONTENT PREVIEW DIALOGS
|
||||
*
|
||||
* Dialogs for previewing and displaying content in full-screen or modal views.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DialogCodePreview** - Full-screen code/HTML preview
|
||||
*
|
||||
* Full-screen dialog for previewing HTML or code in an isolated iframe.
|
||||
* Used by MarkdownContent component for previewing rendered HTML blocks
|
||||
* from code blocks in chat messages.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN Dialog with full viewport layout
|
||||
* - Sandboxed iframe execution (allow-scripts only)
|
||||
* - Clears content when closed for security
|
||||
*
|
||||
* **Features:**
|
||||
* - Full viewport iframe preview
|
||||
* - Sandboxed execution environment
|
||||
* - Close button with mix-blend-difference for visibility over any content
|
||||
* - Automatic content cleanup on close
|
||||
* - Supports HTML preview with proper isolation
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogCodePreview
|
||||
* bind:open={showPreview}
|
||||
* code={htmlContent}
|
||||
* language="html"
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogCodePreview } from './DialogCodePreview.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* ATTACHMENT DIALOGS
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
*
|
||||
* 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';
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
export * from './actions';
|
||||
export * from './badges';
|
||||
export * from './chat';
|
||||
export * from './content';
|
||||
export * from './dialogs';
|
||||
export * from './forms';
|
||||
export * from './mcp';
|
||||
export * from './misc';
|
||||
export * from './models';
|
||||
export * from './navigation';
|
||||
export * from './server';
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* <MarkdownContent content={message.content} {message} />
|
||||
* ```
|
||||
*/
|
||||
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
|
||||
* <SyntaxHighlightedCode code={jsonString} language="json" />
|
||||
* ```
|
||||
*/
|
||||
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
|
||||
* <CollapsibleContentBlock
|
||||
* bind:open
|
||||
* icon={BrainIcon}
|
||||
* title="Thinking..."
|
||||
* isStreaming={true}
|
||||
* >
|
||||
* {reasoningContent}
|
||||
* </CollapsibleContentBlock>
|
||||
* ```
|
||||
*/
|
||||
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
|
||||
* <DropdownMenuSearchable
|
||||
* bind:open
|
||||
* bind:searchValue
|
||||
* placeholder="Search..."
|
||||
* isEmpty={filteredItems.length === 0}
|
||||
* >
|
||||
* {#snippet trigger()}<Button>Select</Button>{/snippet}
|
||||
* {#snippet children()}{#each items as item}<Item {item} />{/each}{/snippet}
|
||||
* </DropdownMenuSearchable>
|
||||
* ```
|
||||
*/
|
||||
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
|
||||
* <DropdownMenuActions
|
||||
* triggerIcon={MoreHorizontal}
|
||||
* triggerTooltip="More actions"
|
||||
* actions={[
|
||||
* { icon: Edit, label: 'Edit', onclick: handleEdit },
|
||||
* { icon: Trash, label: 'Delete', onclick: handleDelete, variant: 'destructive' }
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
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';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* NAVIGATION & 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
|
||||
* <DropdownMenuSearchable
|
||||
* bind:open
|
||||
* bind:searchValue
|
||||
* placeholder="Search..."
|
||||
* isEmpty={filteredItems.length === 0}
|
||||
* >
|
||||
* {#snippet trigger()}<Button>Select</Button>{/snippet}
|
||||
* {#snippet children()}{#each items as item}<Item {item} />{/each}{/snippet}
|
||||
* </DropdownMenuSearchable>
|
||||
* ```
|
||||
*/
|
||||
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
|
||||
* <DropdownMenuActions
|
||||
* triggerIcon={MoreHorizontal}
|
||||
* triggerTooltip="More actions"
|
||||
* actions={[
|
||||
* { icon: Edit, label: 'Edit', onclick: handleEdit },
|
||||
* { icon: Trash, label: 'Delete', onclick: handleDelete, variant: 'destructive' }
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DropdownMenuActions } from './DropdownMenuActions.svelte';
|
||||
Loading…
Reference in New Issue