TUI Renderer, Element Types, and Page Updates
This commit is contained in:
@@ -1,17 +1,31 @@
|
||||
<script lang="ts">
|
||||
import Icon from '@iconify/svelte';
|
||||
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
|
||||
import type { TerminalLine } from './types';
|
||||
import '$lib/assets/css/tui-card.css';
|
||||
import Icon from "@iconify/svelte";
|
||||
import { getButtonStyle, parseColorText, getSegmentStyle } from "./utils";
|
||||
import type { CardLine } from "./types";
|
||||
import TuiLine from "./TuiLine.svelte";
|
||||
import "$lib/assets/css/tui-card.css";
|
||||
|
||||
export let line: TerminalLine;
|
||||
interface Props {
|
||||
line: CardLine;
|
||||
inline?: boolean;
|
||||
}
|
||||
|
||||
$: segments = parseColorText(line.content);
|
||||
$: titleSegments = line.cardTitle ? parseColorText(line.cardTitle) : [];
|
||||
$: footerSegments = line.cardFooter ? parseColorText(line.cardFooter) : [];
|
||||
let { line, inline = false }: Props = $props();
|
||||
|
||||
const segments = $derived(parseColorText(line.content));
|
||||
const titleSegments = $derived(
|
||||
line.cardTitle ? parseColorText(line.cardTitle) : [],
|
||||
);
|
||||
const footerSegments = $derived(
|
||||
line.cardFooter ? parseColorText(line.cardFooter) : [],
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="tui-card" style="--card-accent: {getButtonStyle(line.style)}">
|
||||
<div
|
||||
class="tui-card"
|
||||
class:inline
|
||||
style="--card-color: {getButtonStyle(line.style)}"
|
||||
>
|
||||
{#if line.cardTitle}
|
||||
<div class="card-header">
|
||||
{#if line.icon}
|
||||
@@ -20,7 +34,9 @@
|
||||
<span class="card-title">
|
||||
{#each titleSegments as segment}
|
||||
{#if getSegmentStyle(segment)}
|
||||
<span style={getSegmentStyle(segment)}>{segment.text}</span>
|
||||
<span style={getSegmentStyle(segment)}
|
||||
>{segment.text}</span
|
||||
>
|
||||
{:else}
|
||||
{segment.text}
|
||||
{/if}
|
||||
@@ -28,10 +44,14 @@
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
<div class="card-body">
|
||||
{#if line.image}
|
||||
<img src={line.image} alt={line.imageAlt || ''} class="card-image" />
|
||||
<img
|
||||
src={line.image}
|
||||
alt={line.imageAlt || ""}
|
||||
class="card-image"
|
||||
/>
|
||||
{/if}
|
||||
<div class="card-content">
|
||||
{#each segments as segment}
|
||||
@@ -42,6 +62,25 @@
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{#if line.children && line.children.length > 0}
|
||||
<div
|
||||
class="card-children"
|
||||
class:flex={line.display === "flex"}
|
||||
class:grid={line.display === "grid"}
|
||||
>
|
||||
{#each line.children as child, i}
|
||||
<TuiLine
|
||||
line={child}
|
||||
index={i}
|
||||
segments={parseColorText(child.content)}
|
||||
complete={true}
|
||||
showImage={true}
|
||||
selectedIndex={-1}
|
||||
inline={false}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if line.cardFooter}
|
||||
@@ -61,7 +100,11 @@
|
||||
.tui-card {
|
||||
border: 1px solid var(--terminal-border);
|
||||
border-radius: 6px;
|
||||
background: color-mix(in srgb, var(--terminal-bg) 80%, var(--card-accent) 5%);
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--terminal-bg) 80%,
|
||||
var(--card-accent) 5%
|
||||
);
|
||||
margin: 0.5rem 0;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.2s ease;
|
||||
@@ -109,6 +152,25 @@
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.card-children {
|
||||
margin-top: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.card-children.flex {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.card-children.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-top: 1px solid var(--terminal-border);
|
||||
|
||||
Reference in New Issue
Block a user