CSS Files Styling

This commit is contained in:
2025-11-28 17:43:48 +00:00
parent 8cdb39afbe
commit 4d17b599b3
54 changed files with 4817 additions and 1764 deletions

View File

@@ -0,0 +1,188 @@
<script lang="ts">
import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import type { TerminalLine, FormOption } from './types';
import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-radio.css';
export let line: TerminalLine;
export let inline: boolean = false;
export let value: string = '';
const dispatch = createEventDispatcher<{
change: string;
}>();
$: labelSegments = line.content ? parseColorText(line.content) : [];
$: options = line.radioOptions || [];
$: isDisabled = line.inputDisabled || false;
$: isHorizontal = line.radioHorizontal || false;
function handleSelect(optionValue: string) {
if (isDisabled) return;
value = optionValue;
dispatch('change', value);
}
function handleKeydown(e: KeyboardEvent, optionValue: string) {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
handleSelect(optionValue);
}
}
function getRadioSymbol(selected: boolean): string {
return selected ? '(●)' : '( )';
}
</script>
<div
class="tui-radio-group"
class:inline={inline}
class:disabled={isDisabled}
style="--radio-color: {getButtonStyle(line.style)}"
role="radiogroup"
>
{#if line.content}
<div class="radio-label">
{#if line.icon}
<Icon icon={line.icon} width="14" class="label-icon" />
{/if}
{#each labelSegments as segment}
{#if segment.icon}
<Icon icon={segment.icon} width="14" class="inline-icon" />
{:else if getSegmentStyle(segment)}
<span style={getSegmentStyle(segment)}>{segment.text}</span>
{:else}
{segment.text}
{/if}
{/each}
</div>
{/if}
<div class="radio-options" class:horizontal={isHorizontal}>
{#each options as option}
{@const isSelected = value === option.value}
{@const optionSegments = parseColorText(option.label)}
<div
class="radio-option"
class:selected={isSelected}
class:option-disabled={option.disabled}
role="radio"
aria-checked={isSelected}
aria-disabled={isDisabled || option.disabled}
tabindex={isDisabled || option.disabled ? -1 : 0}
on:click={() => !option.disabled && handleSelect(option.value)}
on:keydown={(e) => !option.disabled && handleKeydown(e, option.value)}
>
<span class="radio-symbol">
{getRadioSymbol(isSelected)}
</span>
{#if option.icon}
<Icon icon={option.icon} width="14" class="option-icon" />
{/if}
<span class="option-label">
{#each optionSegments as segment}
{#if segment.icon}
<Icon icon={segment.icon} width="14" class="inline-icon" />
{:else if getSegmentStyle(segment)}
<span style={getSegmentStyle(segment)}>{segment.text}</span>
{:else}
{segment.text}
{/if}
{/each}
</span>
</div>
{/each}
</div>
</div>
<style>
.tui-radio-group {
margin: 0.5rem 0;
font-size: 0.9rem;
}
.tui-radio-group.inline {
display: inline-flex;
flex-direction: column;
margin: 0 0.75rem 0 0;
}
.tui-radio-group.disabled {
opacity: 0.5;
}
.radio-label {
display: flex;
align-items: center;
gap: 0.35rem;
margin-bottom: 0.5rem;
color: var(--terminal-muted);
font-size: 0.85rem;
}
:global(.label-icon) {
color: var(--radio-color);
}
.radio-options {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.radio-options.horizontal {
flex-direction: row;
flex-wrap: wrap;
gap: 0.75rem;
}
.radio-option {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.35rem 0.5rem;
cursor: pointer;
border-radius: 4px;
transition: all 0.15s ease;
user-select: none;
}
.radio-option:hover:not(.option-disabled) {
background: color-mix(in srgb, var(--radio-color) 10%, transparent);
}
.radio-option:focus-visible {
outline: 1px solid var(--radio-color);
outline-offset: 2px;
}
.radio-option.option-disabled {
opacity: 0.5;
cursor: not-allowed;
}
.radio-symbol {
font-family: inherit;
font-weight: bold;
color: var(--terminal-muted);
transition: color 0.15s ease;
}
.radio-option.selected .radio-symbol {
color: var(--radio-color);
}
:global(.option-icon) {
color: var(--radio-color);
}
.option-label {
color: var(--terminal-text);
}
.radio-option.option-disabled .option-label {
color: var(--terminal-muted);
}
</style>