You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/routes/test/+page.svelte

683 lines
20 KiB

<script lang="ts">
import { actx } from '@/lib/actx/lib/instance_actx.svelte';
import './_components/design-system.css';
// Test data
const locales = ['es', 'en', 'de', 'fr', 'it', 'pt'] as const;
const now = new Date();
let logEntries = $state(actx.logr.getLogs());
// Helpers
function cycleLocale() {
const idx = locales.indexOf(actx.locale as any);
const next = locales[(idx + 1) % locales.length];
actx.ling.setLocale(next);
}
function fireLog(level: 'debug' | 'info' | 'warn' | 'error') {
actx.logr[level](
'test',
{ es: `Log de nivel ${level}`, en: `${level} level log` },
{ ts: Date.now() }
);
logEntries = actx.logr.getLogs();
}
function onLocaleBadgeKeydown(e: KeyboardEvent) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
cycleLocale();
}
}
const LOG_COLORS: Record<string, string> = {
'0': 'var(--color-info)',
'1': 'var(--color-success)',
'2': 'var(--color-warning)',
'3': 'var(--color-error)'
};
// Component groups data
const compGroups = [
{
label: 'Primitivas',
links: [
{ name: 'Separator', href: '/test/separator' },
{ name: 'Label', href: '/test/label' },
{ name: 'Progress', href: '/test/progress' },
{ name: 'Meter', href: '/test/meter' },
{ name: 'Spinner', href: '/test/air/spinner' },
{ name: 'Air Hub', href: '/test/air' },
{ name: 'Toggle', href: '/test/toggle' },
{ name: 'ToggleGroup', href: '/test/toggle-group' },
{ name: 'Pagination', href: '/test/pagination' },
{ name: 'Slider', href: '/test/slider' },
{ name: 'ScrollArea', href: '/test/scroll-area' },
{ name: 'VirtualList', href: '/test/virtual-list' }
]
},
{
label: 'Formulario',
links: [
{ name: 'Switch', href: '/test/switch' },
{ name: 'Checkbox', href: '/test/checkbox' },
{ name: 'RadioGroup', href: '/test/radio-group' },
{ name: 'RatingGroup', href: '/test/rating-group' },
{ name: 'Toolbar', href: '/test/toolbar' },
{ name: 'PinInput', href: '/test/pin-input' }
]
},
{
label: 'Campos',
links: [
{ name: 'Field', href: '/test/field' },
{ name: 'Editable', href: '/test/editable' },
{ name: 'NumberField', href: '/test/number-field' },
{ name: 'DateField', href: '/test/date-picker' },
{ name: 'TimeField', href: '/test/time-field' },
{ name: 'TimeRangeField', href: '/test/time-range-field' },
{ name: 'FileUpload', href: '/test/file-upload' }
]
},
{
label: 'Compuestos',
links: [
{ name: 'Button', href: '/test/button' },
{ name: 'Avatar', href: '/test/avatar' },
{ name: 'AspectRatio', href: '/test/aspect-ratio' },
{ name: 'Collapsible', href: '/test/collapsible' },
{ name: 'Accordion', href: '/test/accordion' },
{ name: 'Tabs', href: '/test/tabs' },
{ name: 'Splitter', href: '/test/splitter' },
{ name: 'Stepper', href: '/test/stepper' }
]
},
{
label: 'Selectores',
links: [
{ name: 'Select', href: '/test/select' },
{ name: 'Combobox', href: '/test/combobox' },
{ name: 'TagsInput', href: '/test/tags-input' }
]
},
{
label: 'Floating',
links: [
{ name: 'Tooltip', href: '/test/tooltip' },
{ name: 'Popover', href: '/test/popover' },
{ name: 'DropdownMenu', href: '/test/dropdown-menu' },
{ name: 'ContextMenu', href: '/test/context-menu' },
{ name: 'Menubar', href: '/test/air/menubar' },
{ name: 'Command', href: '/test/air/command' },
{ name: 'LinkPreview', href: '/test/air/link-preview' }
]
},
{
label: 'Overlays',
links: [
{ name: 'AlertDialog', href: '/test/alert-dialog' },
{ name: 'Dialog', href: '/test/dialog' },
{ name: 'Drawer', href: '/test/drawer' },
{ name: 'Toast', href: '/test/toast' },
{ name: 'Form', href: '/test/air/form' }
]
},
{
label: 'Fechas',
links: [
{ name: 'Calendar', href: '/test/air/calendar' },
{ name: 'RangeCalendar', href: '/test/range-calendar' },
{ name: 'DateRangeField', href: '/test/date-range-field' },
{ name: 'DateRangePicker', href: '/test/date-range-picker' }
]
},
{
label: 'Extra',
links: [
{ name: 'ColorPicker', href: '/test/air/color-picker' },
{ name: 'Modal', href: '/test/modal' }
]
}
];
</script>
<svelte:head>
<title>Test Hub - Component Tests</title>
</svelte:head>
<div class="test-page test-hub">
<!-- Header -->
<header class="test-hub-header">
<div class="test-hub-header-inner">
<div class="test-hub-brand">
<span class="test-hub-logo">ACTX<em>TEST</em></span>
<a href="/test/terra" class="test-hub-sub">→ Terra Hub</a>
</div>
<button class="locale-badge" onclick={cycleLocale} onkeydown={onLocaleBadgeKeydown}>
{actx.locale.toUpperCase()}
</button>
</div>
</header>
<main class="test-hub-main">
<!-- Componentes Section -->
<section class="test-hub-section">
<h2 class="test-hub-section-title">Componentes UI</h2>
<div class="test-hub-groups">
{#each compGroups as group}
<div class="test-hub-group">
<span class="test-hub-group-label">{group.label}</span>
<div class="test-hub-links">
{#each group.links as link}
<a href={link.href} class="test-hub-link">{link.name}</a>
{/each}
</div>
</div>
{/each}
</div>
</section>
<!-- Grid Cards -->
<div class="test-hub-grid">
<!-- LING -->
<section class="test-hub-card test-hub-card--ling">
<h2>ling</h2>
<div class="test-hub-row">
<span class="test-hub-label">t()</span>
<span class="test-hub-value">{actx.t('common.ok')} / {actx.t('common.cancel')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">ts()</span>
<span class="test-hub-value"
>{actx.ts({
es: 'Hola mundo',
en: 'Hello world',
de: 'Hallo Welt',
fr: 'Bonjour monde',
it: 'Ciao mondo',
pt: 'Olá mundo'
})}</span
>
</div>
<div class="test-hub-row">
<span class="test-hub-label">locale</span>
<span class="test-hub-value test-hub-value--accent">{actx.locale}</span>
</div>
<div class="test-hub-locales">
{#each locales as loc}
<button
class="test-hub-loc-btn"
class:active={actx.locale === loc}
onclick={() => actx.ling.setLocale(loc)}>{loc}</button
>
{/each}
</div>
</section>
<!-- NUMR -->
<section class="test-hub-card test-hub-card--numr">
<h2>numr</h2>
<div class="test-hub-row">
<span class="test-hub-label">f(1234567.891)</span>
<span class="test-hub-value">{actx.numr.f(1234567.891)}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">f(0.5, min:2,max:4)</span>
<span class="test-hub-value">{actx.numr.f(0.5, { minDecimals: 2, maxDecimals: 4 })}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">f(1000000)</span>
<span class="test-hub-value">{actx.numr.f(1000000)}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">f(3.14159)</span>
<span class="test-hub-value">{actx.numr.f(3.14159, { maxDecimals: 4 })}</span>
</div>
</section>
<!-- DATI -->
<section class="test-hub-card test-hub-card--dati">
<h2>dati</h2>
<div class="test-hub-row">
<span class="test-hub-label">f(now, 'long')</span>
<span class="test-hub-value">{actx.dati.f(now, 'long')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">f(now, 'short')</span>
<span class="test-hub-value">{actx.dati.f(now, 'short')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">f(now, 'full')</span>
<span class="test-hub-value test-hub-value--small">{actx.dati.f(now, 'full')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">date+time</span>
<span class="test-hub-value">{actx.dati.f(now, { date: 'short', time: 'short' })}</span>
</div>
</section>
<!-- UNIT -->
<section class="test-hub-card test-hub-card--unit">
<h2>unit</h2>
<div class="test-hub-row">
<span class="test-hub-label">75kg → lb</span>
<span class="test-hub-value">{actx.unit.weight.fTo(75, 'kg', 'lb')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">100km → mi</span>
<span class="test-hub-value">{actx.unit.length.fTo(100, 'km', 'mi')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">100°C → °F</span>
<span class="test-hub-value">{actx.unit.temp.fTo(100, 'c', 'f')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">10L → gal</span>
<span class="test-hub-value">{actx.unit.volume.fTo(10, 'l', 'gal')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">sistema</span>
<span class="test-hub-value test-hub-value--accent">{actx.unit.getSystem()}</span>
</div>
<div class="test-hub-btn-row">
<button onclick={() => actx.unit.setSystem('metric')}>metric</button>
<button onclick={() => actx.unit.setSystem('imperial')}>imperial</button>
</div>
</section>
<!-- CURR -->
<section class="test-hub-card test-hub-card--curr">
<h2>curr</h2>
<div class="test-hub-row">
<span class="test-hub-label">moneda activa</span>
<span class="test-hub-value test-hub-value--accent">{actx.curr.getCurrency()}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">f(99.99, symbol)</span>
<span class="test-hub-value">{actx.curr.f(99.99, 'symbol')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">f(99.99, code)</span>
<span class="test-hub-value">{actx.curr.f(99.99, 'code')}</span>
</div>
<div class="test-hub-row">
<span class="test-hub-label">monedas</span>
<span class="test-hub-value test-hub-value--muted"
>{actx.curr.getCurrencies().join(', ') || '(sin definir)'}</span
>
</div>
</section>
<!-- LOGR -->
<section class="test-hub-card test-hub-card--logr">
<h2>logr</h2>
<div class="test-hub-btn-row">
<button onclick={() => fireLog('debug')} class="btn-debug">debug</button>
<button onclick={() => fireLog('info')} class="btn-info">info</button>
<button onclick={() => fireLog('warn')} class="btn-warn">warn</button>
<button onclick={() => fireLog('error')} class="btn-error">error</button>
</div>
<button
class="test-hub-btn-clear"
onclick={() => {
actx.logr.clear();
logEntries = [];
}}>clear</button
>
<div class="test-hub-log-list">
{#each logEntries.slice(-6).reverse() as entry}
<div
class="test-hub-log-entry"
style="border-left-color: {LOG_COLORS[String(entry.level)]}"
>
<span class="test-hub-log-level" style="color: {LOG_COLORS[String(entry.level)]}"
>{entry.level}</span
>
<span class="test-hub-log-msg">{actx.ts(entry.message)}</span>
</div>
{/each}
{#if logEntries.length === 0}
<span class="test-hub-value--muted">sin logs</span>
{/if}
</div>
</section>
</div>
</main>
</div>
<style>
.test-hub {
min-height: 100vh;
}
/* ── Header ───────────────────────────────────────────────────────────────── */
.test-hub-header {
position: sticky;
top: 0;
z-index: 100;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
}
.test-hub-header-inner {
max-width: 1400px;
margin: 0 auto;
padding: var(--spacing-4) var(--spacing-6);
display: flex;
align-items: center;
justify-content: space-between;
}
.test-hub-brand {
display: flex;
align-items: center;
gap: var(--spacing-4);
}
.test-hub-logo {
font-size: var(--text-base);
font-weight: 700;
letter-spacing: 0.15em;
text-transform: uppercase;
color: var(--color-text);
}
.test-hub-logo em {
color: var(--color-primary);
font-style: normal;
}
.test-hub-sub {
font-size: var(--text-xs);
color: var(--color-text-muted);
text-decoration: none;
padding: var(--spacing-1) var(--spacing-3);
border-radius: var(--radius-full);
background: var(--color-primary-bg);
border: 1px solid var(--color-primary-border);
transition: all var(--transition-fast);
}
.test-hub-sub:hover {
background: var(--color-primary);
color: var(--color-text);
}
.locale-badge {
padding: var(--spacing-1) var(--spacing-3);
border: 1px solid var(--color-primary);
border-radius: var(--radius-sm);
font-size: var(--text-xs);
font-weight: 700;
letter-spacing: 0.1em;
cursor: pointer;
color: var(--color-primary);
background: var(--color-primary-bg);
transition: all var(--transition-fast);
}
.locale-badge:hover {
background: var(--color-primary);
color: var(--color-text);
}
/* ── Main ────────────────────────────────────────────────────────────────── */
.test-hub-main {
max-width: 1400px;
margin: 0 auto;
padding: var(--spacing-8) var(--spacing-6);
display: flex;
flex-direction: column;
gap: var(--spacing-8);
}
/* ── Section Componentes ──────────────────────────────────────────────────── */
.test-hub-section {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-top: 3px solid var(--color-primary);
border-radius: var(--radius-lg);
padding: var(--spacing-6);
}
.test-hub-section-title {
font-size: var(--text-xs);
font-weight: 700;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--color-text-muted);
margin: 0 0 var(--spacing-4) 0;
}
.test-hub-groups {
display: flex;
gap: var(--spacing-8);
flex-wrap: wrap;
}
.test-hub-group {
display: flex;
flex-direction: column;
gap: var(--spacing-3);
}
.test-hub-group-label {
font-size: var(--text-xs);
font-weight: 700;
letter-spacing: 0.15em;
text-transform: uppercase;
color: var(--color-text-muted);
}
.test-hub-links {
display: flex;
flex-direction: column;
gap: var(--spacing-1);
}
.test-hub-link {
font-size: var(--text-sm);
font-weight: 500;
color: var(--color-primary);
text-decoration: none;
padding: var(--spacing-1) 0;
transition: opacity var(--transition-fast);
}
.test-hub-link:hover {
opacity: 0.7;
text-decoration: underline;
}
/* ── Grid ────────────────────────────────────────────────────────────────── */
.test-hub-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: var(--spacing-4);
}
/* ── Cards ───────────────────────────────────────────────────────────────── */
.test-hub-card {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--spacing-5);
display: flex;
flex-direction: column;
gap: var(--spacing-4);
transition: border-color var(--transition-normal);
}
.test-hub-card:hover {
border-color: var(--color-border-focus);
}
.test-hub-card h2 {
font-size: var(--text-xs);
font-weight: 700;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--color-text-muted);
margin: 0;
padding-bottom: var(--spacing-2);
border-bottom: 1px solid var(--color-border-muted);
}
/* Card accent borders */
.test-hub-card--ling {
border-top: 3px solid var(--color-info);
}
.test-hub-card--numr {
border-top: 3px solid var(--color-success);
}
.test-hub-card--dati {
border-top: 3px solid #3b82f6;
}
.test-hub-card--unit {
border-top: 3px solid var(--color-warning);
}
.test-hub-card--curr {
border-top: 3px solid #ec4899;
}
.test-hub-card--logr {
border-top: 3px solid var(--color-primary);
}
/* ── Rows ────────────────────────────────────────────────────────────────── */
.test-hub-row {
display: flex;
align-items: baseline;
gap: var(--spacing-3);
font-size: var(--text-sm);
}
.test-hub-label {
color: var(--color-text-muted);
font-size: var(--text-xs);
min-width: 140px;
flex-shrink: 0;
font-family: var(--font-mono);
}
.test-hub-value {
font-weight: 500;
color: var(--color-text);
}
.test-hub-value--small {
font-size: var(--text-xs);
}
.test-hub-value--accent {
color: var(--color-primary);
font-weight: 700;
}
.test-hub-value--muted {
color: var(--color-text-dim);
font-style: italic;
}
/* ── Buttons ─────────────────────────────────────────────────────────────── */
.test-hub-btn-row {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-2);
}
.test-hub-card button {
padding: var(--spacing-2) var(--spacing-3);
background: var(--color-background);
color: var(--color-text);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
font-family: inherit;
font-size: var(--text-xs);
font-weight: 600;
letter-spacing: 0.05em;
cursor: pointer;
transition: all var(--transition-fast);
}
.test-hub-card button:hover {
background: var(--color-surface-elevated);
border-color: var(--color-border-focus);
}
.btn-debug {
color: var(--color-info);
border-color: rgba(96, 165, 250, 0.3);
}
.btn-info {
color: var(--color-success);
border-color: rgba(74, 222, 128, 0.3);
}
.btn-warn {
color: var(--color-warning);
border-color: rgba(251, 191, 36, 0.3);
}
.btn-error {
color: var(--color-error);
border-color: rgba(248, 113, 113, 0.3);
}
.test-hub-btn-clear {
background: transparent !important;
border-color: var(--color-border-muted) !important;
color: var(--color-text-dim) !important;
font-size: 0.6875rem;
align-self: flex-start;
}
/* ── Locale Buttons ───────────────────────────────────────────────────────── */
.test-hub-locales {
display: flex;
gap: var(--spacing-2);
flex-wrap: wrap;
}
.test-hub-loc-btn {
background: transparent;
border: 1px solid var(--color-border-muted);
color: var(--color-text-dim);
padding: var(--spacing-1) var(--spacing-3);
font-size: var(--text-xs);
border-radius: var(--radius-sm);
}
.test-hub-loc-btn.active {
background: var(--color-primary-bg);
border-color: var(--color-primary);
color: var(--color-primary);
}
/* ── Log List ────────────────────────────────────────────────────────────── */
.test-hub-log-list {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
}
.test-hub-log-entry {
display: flex;
gap: var(--spacing-3);
align-items: baseline;
padding: var(--spacing-2) var(--spacing-3);
font-size: var(--text-xs);
background: var(--color-background);
border-radius: var(--radius-sm);
border-left: 3px solid var(--color-border-muted);
}
.test-hub-log-level {
font-weight: 700;
font-size: 0.6875rem;
min-width: 2rem;
font-family: var(--font-mono);
}
.test-hub-log-msg {
color: var(--color-text-muted);
}
</style>

Powered by TurnKey Linux.