TUI Renderer, Element Types, and Page Updates

This commit is contained in:
2025-11-30 18:26:56 -05:00
parent f09c198f17
commit 1167c686e2
31 changed files with 1642 additions and 809 deletions

View File

@@ -1,54 +1,64 @@
<script lang="ts">
import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types';
import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-input.css';
import Icon from "@iconify/svelte";
import { getButtonStyle, parseColorText, getSegmentStyle } from "./utils";
import { themeColors } from "$lib/stores/theme";
import type { InputLine } from "./types";
import "$lib/assets/css/tui-input.css";
export let line: TerminalLine;
export let inline: boolean = false;
export let value: string = '';
interface Props {
line: InputLine;
inline?: boolean;
value?: string;
oninput?: (value: string) => void;
onchange?: (value: string) => void;
onfocus?: () => void;
onblur?: () => void;
}
const dispatch = createEventDispatcher<{
input: string;
change: string;
focus: void;
blur: void;
}>();
let {
line,
inline = false,
value = $bindable(""),
oninput,
onchange,
onfocus,
onblur,
}: Props = $props();
$: labelSegments = line.content ? parseColorText(line.content, $themeColors.colorMap) : [];
$: placeholder = line.inputPlaceholder || '';
$: inputType = line.inputType || 'text';
$: isDisabled = line.inputDisabled || false;
$: hasError = line.inputError;
$: errorMessage = line.inputErrorMessage || '';
$: prefix = line.inputPrefix || '';
$: suffix = line.inputSuffix || '';
const labelSegments = $derived(
line.content ? parseColorText(line.content, $themeColors.colorMap) : [],
);
const placeholder = $derived(line.inputPlaceholder || "");
const inputType = $derived(line.inputType || "text");
const isDisabled = $derived(line.inputDisabled || false);
const hasError = $derived(line.inputError);
const errorMessage = $derived(line.inputErrorMessage || "");
const prefix = $derived(line.inputPrefix || "");
const suffix = $derived(line.inputSuffix || "");
function handleInput(e: Event) {
const target = e.target as HTMLInputElement;
value = target.value;
dispatch('input', value);
oninput?.(value);
}
function handleChange(e: Event) {
const target = e.target as HTMLInputElement;
dispatch('change', target.value);
onchange?.(target.value);
}
function handleFocus() {
dispatch('focus');
onfocus?.();
}
function handleBlur() {
dispatch('blur');
onblur?.();
}
</script>
<div
class="tui-input"
class:inline={inline}
<div
class="tui-input"
class:inline
class:error={hasError}
class:disabled={isDisabled}
style="--input-color: {getButtonStyle(line.style)}"
@@ -69,7 +79,7 @@
{/each}
</label>
{/if}
<div class="input-wrapper">
<span class="input-prompt"></span>
{#if prefix}
@@ -78,12 +88,12 @@
<input
type={inputType}
{placeholder}
{value}
bind:value
disabled={isDisabled}
on:input={handleInput}
on:change={handleChange}
on:focus={handleFocus}
on:blur={handleBlur}
oninput={handleInput}
onchange={handleChange}
onfocus={handleFocus}
onblur={handleBlur}
/>
{#if suffix}
<span class="input-affix suffix">{suffix}</span>
@@ -136,7 +146,8 @@
.input-wrapper:focus-within {
border-color: var(--input-color);
box-shadow: 0 0 0 1px color-mix(in srgb, var(--input-color) 30%, transparent);
box-shadow: 0 0 0 1px
color-mix(in srgb, var(--input-color) 30%, transparent);
}
.tui-input.error .input-wrapper {