CSS Files Styling
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
<script lang="ts">
|
||||
import Icon from '@iconify/svelte';
|
||||
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
|
||||
import type { TerminalLine } from './types';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import '$lib/assets/css/tui-toggle.css';
|
||||
|
||||
export let line: TerminalLine;
|
||||
export let inline: boolean = false;
|
||||
export let checked: boolean = false;
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
change: boolean;
|
||||
}>();
|
||||
|
||||
$: labelSegments = line.content ? parseColorText(line.content) : [];
|
||||
$: isDisabled = line.inputDisabled || false;
|
||||
$: onLabel = line.toggleOnLabel || 'ON';
|
||||
$: offLabel = line.toggleOffLabel || 'OFF';
|
||||
$: showLabels = line.toggleShowLabels !== false;
|
||||
|
||||
function handleToggle() {
|
||||
if (isDisabled) return;
|
||||
checked = !checked;
|
||||
dispatch('change', checked);
|
||||
}
|
||||
|
||||
function handleKeydown(e: KeyboardEvent) {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
handleToggle();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="tui-toggle"
|
||||
class:inline={inline}
|
||||
class:checked={checked}
|
||||
class:disabled={isDisabled}
|
||||
style="--toggle-color: {getButtonStyle(line.style)}"
|
||||
role="switch"
|
||||
aria-checked={checked}
|
||||
aria-disabled={isDisabled}
|
||||
tabindex={isDisabled ? -1 : 0}
|
||||
on:click={handleToggle}
|
||||
on:keydown={handleKeydown}
|
||||
>
|
||||
{#if line.icon}
|
||||
<Icon icon={line.icon} width="14" class="toggle-icon" />
|
||||
{/if}
|
||||
|
||||
{#if line.content}
|
||||
<span class="toggle-label">
|
||||
{#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}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<div class="toggle-track">
|
||||
{#if showLabels}
|
||||
<span class="toggle-off-label">{offLabel}</span>
|
||||
{/if}
|
||||
<span class="toggle-switch">
|
||||
<span class="toggle-knob">{checked ? '●' : '○'}</span>
|
||||
</span>
|
||||
{#if showLabels}
|
||||
<span class="toggle-on-label">{onLabel}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.tui-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin: 0.35rem 0;
|
||||
padding: 0.35rem 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.15s ease;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tui-toggle.inline {
|
||||
display: inline-flex;
|
||||
margin: 0 0.75rem 0 0;
|
||||
}
|
||||
|
||||
.tui-toggle:hover:not(.disabled) {
|
||||
background: color-mix(in srgb, var(--toggle-color) 10%, transparent);
|
||||
}
|
||||
|
||||
.tui-toggle:focus-visible {
|
||||
outline: 1px solid var(--toggle-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.tui-toggle.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
:global(.toggle-icon) {
|
||||
color: var(--toggle-color);
|
||||
}
|
||||
|
||||
.toggle-label {
|
||||
color: var(--terminal-text);
|
||||
}
|
||||
|
||||
.toggle-track {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
background: color-mix(in srgb, var(--terminal-bg) 80%, black);
|
||||
border: 1px solid var(--terminal-muted);
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.tui-toggle.checked .toggle-track {
|
||||
border-color: var(--toggle-color);
|
||||
background: color-mix(in srgb, var(--toggle-color) 15%, transparent);
|
||||
}
|
||||
|
||||
.toggle-off-label,
|
||||
.toggle-on-label {
|
||||
color: var(--terminal-muted);
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
min-width: 2rem;
|
||||
text-align: center;
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
|
||||
.tui-toggle:not(.checked) .toggle-off-label {
|
||||
color: var(--terminal-text);
|
||||
}
|
||||
|
||||
.tui-toggle.checked .toggle-on-label {
|
||||
color: var(--toggle-color);
|
||||
}
|
||||
|
||||
.toggle-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.toggle-knob {
|
||||
font-size: 1rem;
|
||||
color: var(--terminal-muted);
|
||||
transition: all 0.2s ease;
|
||||
transform: translateX(-0.5rem);
|
||||
}
|
||||
|
||||
.tui-toggle.checked .toggle-knob {
|
||||
color: var(--toggle-color);
|
||||
transform: translateX(0.5rem);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user