TUI Renderer Update
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
<script lang="ts">
|
||||
import Icon from '@iconify/svelte';
|
||||
import { getSegmentStyle, getLinePrefix } from './utils';
|
||||
import { handleNavigation } from './terminal-keyboard';
|
||||
import { user } from '$lib/config';
|
||||
import TuiButton from './TuiButton.svelte';
|
||||
import TuiLink from './TuiLink.svelte';
|
||||
import TuiCard from './TuiCard.svelte';
|
||||
import TuiProgress from './TuiProgress.svelte';
|
||||
import TuiAccordion from './TuiAccordion.svelte';
|
||||
import TuiTable from './TuiTable.svelte';
|
||||
import TuiTooltip from './TuiTooltip.svelte';
|
||||
import TuiCardGrid from './TuiCardGrid.svelte';
|
||||
import TuiInput from './TuiInput.svelte';
|
||||
import TuiTextarea from './TuiTextarea.svelte';
|
||||
import TuiCheckbox from './TuiCheckbox.svelte';
|
||||
import TuiRadio from './TuiRadio.svelte';
|
||||
import TuiSelect from './TuiSelect.svelte';
|
||||
import TuiToggle from './TuiToggle.svelte';
|
||||
import TuiGroup from './TuiGroup.svelte';
|
||||
import type { TerminalLine, TextSegment } from './types';
|
||||
|
||||
interface Props {
|
||||
line: TerminalLine;
|
||||
index: number;
|
||||
segments: TextSegment[];
|
||||
complete?: boolean;
|
||||
showImage?: boolean;
|
||||
selectedIndex?: number;
|
||||
inline?: boolean;
|
||||
showCursor?: boolean;
|
||||
onButtonClick?: (idx: number) => void;
|
||||
onHoverButton?: (idx: number) => void;
|
||||
onLinkClick?: (idx: number) => void;
|
||||
}
|
||||
|
||||
let {
|
||||
line,
|
||||
index,
|
||||
segments,
|
||||
complete = true,
|
||||
showImage = false,
|
||||
selectedIndex = -1,
|
||||
inline = false,
|
||||
showCursor = false,
|
||||
onButtonClick = () => {},
|
||||
onHoverButton = () => {},
|
||||
onLinkClick = () => {}
|
||||
}: Props = $props();
|
||||
|
||||
// Component types that have their own wrapper
|
||||
const componentTypes = new Set(['button', 'card', 'cardgrid', 'progress', 'accordion', 'table', 'input', 'textarea', 'checkbox', 'radio', 'select', 'toggle', 'group']);
|
||||
|
||||
// Types that need special handling
|
||||
const isComponent = $derived(componentTypes.has(line.type));
|
||||
const isBlank = $derived(line.type === 'blank');
|
||||
const isDivider = $derived(line.type === 'divider');
|
||||
const isImage = $derived(line.type === 'image');
|
||||
const isPrompt = $derived(line.type === 'command' || line.type === 'prompt');
|
||||
const isHeader = $derived(line.type === 'header');
|
||||
const isLink = $derived(line.type === 'link');
|
||||
const isTooltip = $derived(line.type === 'tooltip');
|
||||
</script>
|
||||
|
||||
{#if isBlank}
|
||||
{#if inline}<span class="inline-blank"></span>{:else}<div class="tui-line blank"></div>{/if}
|
||||
{:else if isDivider}
|
||||
<div class="tui-divider" id={line.id}>
|
||||
<span class="divider-line"></span>
|
||||
{#if line.content}<span class="divider-text">{line.content}</span>{/if}
|
||||
<span class="divider-line"></span>
|
||||
</div>
|
||||
{:else if line.type === 'button'}
|
||||
<TuiButton {line} {index} selected={selectedIndex === index} onClick={onButtonClick} onHover={onHoverButton} {inline} />
|
||||
{:else if isLink}
|
||||
{#if inline}
|
||||
<TuiLink {line} onClick={() => handleNavigation(line)} />
|
||||
{:else}
|
||||
<div class="tui-line link"><TuiLink {line} onClick={() => onLinkClick(index)} /></div>
|
||||
{/if}
|
||||
{:else if isTooltip}
|
||||
{#if inline}<TuiTooltip {line} />{:else}<div class="tui-line"><TuiTooltip {line} /></div>{/if}
|
||||
{:else if line.type === 'card'}
|
||||
<TuiCard {line} />
|
||||
{:else if line.type === 'cardgrid'}
|
||||
<TuiCardGrid {line} />
|
||||
{:else if line.type === 'progress'}
|
||||
<TuiProgress {line} {inline} />
|
||||
{:else if line.type === 'accordion'}
|
||||
<TuiAccordion {line} />
|
||||
{:else if line.type === 'table'}
|
||||
<TuiTable {line} />
|
||||
{:else if line.type === 'input'}
|
||||
<TuiInput {line} {inline} />
|
||||
{:else if line.type === 'textarea'}
|
||||
<TuiTextarea {line} />
|
||||
{:else if line.type === 'checkbox'}
|
||||
<TuiCheckbox {line} {inline} />
|
||||
{:else if line.type === 'radio'}
|
||||
<TuiRadio {line} />
|
||||
{:else if line.type === 'select'}
|
||||
<TuiSelect {line} />
|
||||
{:else if line.type === 'toggle'}
|
||||
<TuiToggle {line} {inline} />
|
||||
{:else if line.type === 'group'}
|
||||
<TuiGroup {line} {inline} {onButtonClick} {onHoverButton} {onLinkClick} />
|
||||
{:else if isImage && showImage}
|
||||
<div class="tui-image" class:inline-image={inline}>
|
||||
<img src={line.image} alt={line.imageAlt || 'Image'} style="max-width: {line.imageWidth || 300}px" />
|
||||
{#if line.content}<span class="image-caption">{line.content}</span>{/if}
|
||||
</div>
|
||||
{:else if !isImage}
|
||||
{#if inline}
|
||||
<span class="inline-content {line.type}">
|
||||
{getLinePrefix(line.type)}{#each segments as seg}{#if seg.icon}<Icon icon={seg.icon} width="14" class="inline-icon" />{:else if getSegmentStyle(seg)}<span style={getSegmentStyle(seg)}>{seg.text}</span>{:else}{seg.text}{/if}{/each}
|
||||
</span>
|
||||
{:else}
|
||||
<div class="tui-line {line.type}" class:complete id={line.id}>
|
||||
{#if isPrompt}
|
||||
<span class="prompt">
|
||||
<span class="user">{user.username}</span><span class="at">@</span><span class="host">{user.hostname}</span>
|
||||
<span class="separator">:</span><span class="path">~</span><span class="symbol">$</span>
|
||||
</span>
|
||||
{/if}
|
||||
{#if isHeader}
|
||||
<span class="content header-text">
|
||||
<Icon icon="mdi:pound" width="14" class="header-icon" />
|
||||
{#each segments as seg}{#if seg.icon}<Icon icon={seg.icon} width="16" class="inline-icon" />{:else if getSegmentStyle(seg)}<span style={getSegmentStyle(seg)}>{seg.text}</span>{:else}{seg.text}{/if}{/each}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="content">
|
||||
{getLinePrefix(line.type)}{#each segments as seg}{#if seg.icon}<Icon icon={seg.icon} width="14" class="inline-icon" />{:else if getSegmentStyle(seg)}<span style={getSegmentStyle(seg)}>{seg.text}</span>{:else}{seg.text}{/if}{/each}
|
||||
</span>
|
||||
{/if}
|
||||
{#if showCursor}<span class="cursor"></span>{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
Reference in New Issue
Block a user