|
|
|
|
@ -1,255 +1,510 @@
|
|
|
|
|
<script lang="ts">
|
|
|
|
|
import { AcelConfig, DatePicker } from '$uix/terra';
|
|
|
|
|
import { CalendarDate, type DateValue, getLocalTimeZone, today, type DatiDateOrder } from '$lib/glob/lib';
|
|
|
|
|
|
|
|
|
|
import { TerraConfig, DatePicker } from '$uix/terra';
|
|
|
|
|
|
|
|
|
|
import { CalendarDate, type DateValue, getLocalTimeZone, today, type DateOrder } from '$lib/util/dates';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const tz = getLocalTimeZone();
|
|
|
|
|
|
|
|
|
|
const now = today(tz);
|
|
|
|
|
|
|
|
|
|
const LOCALES = [
|
|
|
|
|
|
|
|
|
|
{ id: 'es-ES', label: 'es-ES' },
|
|
|
|
|
|
|
|
|
|
{ id: 'en-US', label: 'en-US' },
|
|
|
|
|
|
|
|
|
|
{ id: 'de-DE', label: 'de-DE' },
|
|
|
|
|
|
|
|
|
|
];
|
|
|
|
|
const ORDERS: DatiDateOrder[] = ['DMY', 'MDY', 'YMD'];
|
|
|
|
|
|
|
|
|
|
const ORDERS: DateOrder[] = ['DMY', 'MDY', 'YMD'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let locale = $state('es-ES');
|
|
|
|
|
let dateOrder = $state<DatiDateOrder>('DMY');
|
|
|
|
|
|
|
|
|
|
let dateOrder = $state<DateOrder>('DMY');
|
|
|
|
|
|
|
|
|
|
let value1 = $state<DateValue | undefined>(new CalendarDate(now.year, now.month, now.day));
|
|
|
|
|
|
|
|
|
|
let value2 = $state<DateValue | undefined>(new CalendarDate(now.year, now.month, Math.min(now.day + 3, 28)));
|
|
|
|
|
|
|
|
|
|
let value3 = $state<DateValue | undefined>(undefined);
|
|
|
|
|
|
|
|
|
|
let open3 = $state(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function fmt(value: DateValue | undefined) {
|
|
|
|
|
|
|
|
|
|
if (!value) return '—';
|
|
|
|
|
|
|
|
|
|
return `${value.year}-${String(value.month).padStart(2, '0')}-${String(value.day).padStart(2, '0')}`;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="page">
|
|
|
|
|
|
|
|
|
|
<header class="hero">
|
|
|
|
|
|
|
|
|
|
<p class="eyebrow">acel · date-picker</p>
|
|
|
|
|
|
|
|
|
|
<h1>DatePicker</h1>
|
|
|
|
|
<p class="sub">Demo para probar picker simple con `locale`, `dateOrder` y herencia vía `AcelConfig`.</p>
|
|
|
|
|
|
|
|
|
|
<p class="sub">Demo para probar picker simple con `locale`, `dateOrder` y herencia vía `TerraConfig`.</p>
|
|
|
|
|
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section class="toolbar">
|
|
|
|
|
|
|
|
|
|
<div class="group">
|
|
|
|
|
|
|
|
|
|
<span>Locale</span>
|
|
|
|
|
|
|
|
|
|
{#each LOCALES as option}
|
|
|
|
|
|
|
|
|
|
<button class:selected={locale === option.id} onclick={() => (locale = option.id)}>{option.label}</button>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="group">
|
|
|
|
|
|
|
|
|
|
<span>Date order</span>
|
|
|
|
|
|
|
|
|
|
{#each ORDERS as order}
|
|
|
|
|
|
|
|
|
|
<button class:selected={dateOrder === order} onclick={() => (dateOrder = order)}>{order}</button>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<main class="grid">
|
|
|
|
|
|
|
|
|
|
<section class="card">
|
|
|
|
|
|
|
|
|
|
<h2>Básico</h2>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Root bind:value={value1} {locale} {dateOrder}>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Label class="dp-label">Fecha</DatePicker.Label>
|
|
|
|
|
|
|
|
|
|
<div class="field-row">
|
|
|
|
|
|
|
|
|
|
<DatePicker.Input class="dp-input">
|
|
|
|
|
|
|
|
|
|
{#snippet children({ segments })}
|
|
|
|
|
|
|
|
|
|
{#each segments as { part, value }}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Segment {part} class="dp-seg">{value}</DatePicker.Segment>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
{/snippet}
|
|
|
|
|
|
|
|
|
|
</DatePicker.Input>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Trigger class="dp-trigger">📅</DatePicker.Trigger>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Content class="dp-popover" sideOffset={8}>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Calendar class="cal">
|
|
|
|
|
|
|
|
|
|
{#snippet children({ months, weekdays })}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Header class="cal-hd">
|
|
|
|
|
|
|
|
|
|
<DatePicker.PrevButton class="cal-btn">‹</DatePicker.PrevButton>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Heading class="cal-heading" />
|
|
|
|
|
|
|
|
|
|
<DatePicker.NextButton class="cal-btn">›</DatePicker.NextButton>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Header>
|
|
|
|
|
|
|
|
|
|
{#each months as month}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Grid class="cal-grid">
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridHead>
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{#each weekdays as day}
|
|
|
|
|
|
|
|
|
|
<DatePicker.HeadCell class="cal-th">{day}</DatePicker.HeadCell>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridHead>
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridBody>
|
|
|
|
|
|
|
|
|
|
{#each month.weeks as week}
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{#each week as date}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Cell {date} month={month.value} class="cal-td">
|
|
|
|
|
|
|
|
|
|
<DatePicker.Day class="cal-day" />
|
|
|
|
|
|
|
|
|
|
</DatePicker.Cell>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridBody>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Grid>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
{/snippet}
|
|
|
|
|
|
|
|
|
|
</DatePicker.Calendar>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Content>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Root>
|
|
|
|
|
|
|
|
|
|
<div class="value">{fmt(value1)}</div>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section class="card">
|
|
|
|
|
|
|
|
|
|
<h2>Dos meses</h2>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Root bind:value={value2} {locale} {dateOrder} numberOfMonths={2}>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Label class="dp-label">Fecha extendida</DatePicker.Label>
|
|
|
|
|
|
|
|
|
|
<div class="field-row">
|
|
|
|
|
|
|
|
|
|
<DatePicker.Input class="dp-input">
|
|
|
|
|
|
|
|
|
|
{#snippet children({ segments })}
|
|
|
|
|
|
|
|
|
|
{#each segments as { part, value }}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Segment {part} class="dp-seg">{value}</DatePicker.Segment>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
{/snippet}
|
|
|
|
|
|
|
|
|
|
</DatePicker.Input>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Trigger class="dp-trigger">📅</DatePicker.Trigger>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Content class="dp-popover" sideOffset={8}>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Calendar class="cal">
|
|
|
|
|
|
|
|
|
|
{#snippet children({ months, weekdays })}
|
|
|
|
|
|
|
|
|
|
<div class="two-month-layout">
|
|
|
|
|
|
|
|
|
|
{#each months as month, i}
|
|
|
|
|
|
|
|
|
|
<div class="month-col">
|
|
|
|
|
|
|
|
|
|
<div class="month-nav">
|
|
|
|
|
|
|
|
|
|
{#if i === 0}
|
|
|
|
|
|
|
|
|
|
<DatePicker.PrevButton class="cal-btn"><EFBFBD></DatePicker.PrevButton>
|
|
|
|
|
|
|
|
|
|
{:else}
|
|
|
|
|
|
|
|
|
|
<span></span>
|
|
|
|
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Heading class="cal-heading" />
|
|
|
|
|
|
|
|
|
|
{#if i === months.length - 1}
|
|
|
|
|
|
|
|
|
|
<DatePicker.NextButton class="cal-btn"><EFBFBD></DatePicker.NextButton>
|
|
|
|
|
|
|
|
|
|
{:else}
|
|
|
|
|
|
|
|
|
|
<span></span>
|
|
|
|
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Grid class="cal-grid">
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridHead>
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{#each weekdays as day}
|
|
|
|
|
|
|
|
|
|
<DatePicker.HeadCell class="cal-th">{day}</DatePicker.HeadCell>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridHead>
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridBody>
|
|
|
|
|
|
|
|
|
|
{#each month.weeks as week}
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{#each week as date}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Cell {date} month={month.value} class="cal-td">
|
|
|
|
|
|
|
|
|
|
<DatePicker.Day class="cal-day" />
|
|
|
|
|
|
|
|
|
|
</DatePicker.Cell>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridBody>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Grid>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/snippet}
|
|
|
|
|
|
|
|
|
|
</DatePicker.Calendar>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Content>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Root>
|
|
|
|
|
|
|
|
|
|
<div class="value">{fmt(value2)}</div>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section class="card">
|
|
|
|
|
<h2>Vía AcelConfig</h2>
|
|
|
|
|
<AcelConfig defaultLocale={locale} defaultDateOrder={dateOrder}>
|
|
|
|
|
|
|
|
|
|
<h2>Vía TerraConfig</h2>
|
|
|
|
|
|
|
|
|
|
<TerraConfig defaultLocale={locale} defaultDateOrder={dateOrder}>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Root bind:value={value3} bind:open={open3}>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Label class="dp-label">Fecha heredada</DatePicker.Label>
|
|
|
|
|
|
|
|
|
|
<div class="field-row">
|
|
|
|
|
|
|
|
|
|
<DatePicker.Input class="dp-input">
|
|
|
|
|
|
|
|
|
|
{#snippet children({ segments })}
|
|
|
|
|
|
|
|
|
|
{#each segments as { part, value }}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Segment {part} class="dp-seg">{value}</DatePicker.Segment>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
{/snippet}
|
|
|
|
|
|
|
|
|
|
</DatePicker.Input>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Trigger class="dp-trigger">📅</DatePicker.Trigger>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Content class="dp-popover" sideOffset={8}>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Calendar class="cal">
|
|
|
|
|
|
|
|
|
|
{#snippet children({ months, weekdays })}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Header class="cal-hd">
|
|
|
|
|
|
|
|
|
|
<DatePicker.PrevButton class="cal-btn"><EFBFBD></DatePicker.PrevButton>
|
|
|
|
|
|
|
|
|
|
<DatePicker.Heading class="cal-heading" />
|
|
|
|
|
|
|
|
|
|
<DatePicker.NextButton class="cal-btn"><EFBFBD></DatePicker.NextButton>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Header>
|
|
|
|
|
|
|
|
|
|
{#each months as month}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Grid class="cal-grid">
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridHead>
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{#each weekdays as day}
|
|
|
|
|
|
|
|
|
|
<DatePicker.HeadCell class="cal-th">{day}</DatePicker.HeadCell>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridHead>
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridBody>
|
|
|
|
|
|
|
|
|
|
{#each month.weeks as week}
|
|
|
|
|
|
|
|
|
|
<DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{#each week as date}
|
|
|
|
|
|
|
|
|
|
<DatePicker.Cell {date} month={month.value} class="cal-td">
|
|
|
|
|
|
|
|
|
|
<DatePicker.Day class="cal-day" />
|
|
|
|
|
|
|
|
|
|
</DatePicker.Cell>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridRow>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
</DatePicker.GridBody>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Grid>
|
|
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
{/snippet}
|
|
|
|
|
|
|
|
|
|
</DatePicker.Calendar>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Content>
|
|
|
|
|
|
|
|
|
|
</DatePicker.Root>
|
|
|
|
|
</AcelConfig>
|
|
|
|
|
|
|
|
|
|
</TerraConfig>
|
|
|
|
|
|
|
|
|
|
<div class="value">{fmt(value3)}</div>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
</main>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
|
|
|
|
|
:global(*, *::before, *::after) { box-sizing: border-box; }
|
|
|
|
|
|
|
|
|
|
.page { min-height: 100vh; background: #0f1117; color: #e5e7eb; font-family: Inter, system-ui, sans-serif; padding: 1.5rem; }
|
|
|
|
|
|
|
|
|
|
.hero, .toolbar, .grid { max-width: 1100px; margin: 0 auto; }
|
|
|
|
|
|
|
|
|
|
.hero { margin-bottom: 1rem; }
|
|
|
|
|
|
|
|
|
|
.eyebrow { margin: 0 0 .35rem; font-size: .75rem; letter-spacing: .14em; text-transform: uppercase; color: #60a5fa; }
|
|
|
|
|
|
|
|
|
|
h1 { margin: 0; font-size: 2rem; }
|
|
|
|
|
|
|
|
|
|
.sub { margin: .4rem 0 0; color: #94a3b8; }
|
|
|
|
|
|
|
|
|
|
.toolbar { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1.25rem; }
|
|
|
|
|
|
|
|
|
|
.group { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
|
|
|
|
|
|
|
|
|
|
.group span { font-size: .8rem; color: #94a3b8; }
|
|
|
|
|
|
|
|
|
|
button { border: 1px solid #334155; background: #111827; color: #cbd5e1; border-radius: 999px; padding: .35rem .7rem; cursor: pointer; }
|
|
|
|
|
|
|
|
|
|
button.selected { border-color: #60a5fa; color: #eff6ff; background: #172554; }
|
|
|
|
|
|
|
|
|
|
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1rem; }
|
|
|
|
|
|
|
|
|
|
.card { background: #111827; border: 1px solid #1f2937; border-radius: 16px; padding: 1rem; display: flex; flex-direction: column; gap: .75rem; }
|
|
|
|
|
|
|
|
|
|
.card h2 { margin: 0; }
|
|
|
|
|
|
|
|
|
|
:global(.dp-label) { display: block; font-size: .78rem; color: #93c5fd; margin-bottom: .35rem; }
|
|
|
|
|
|
|
|
|
|
.field-row { display: flex; align-items: center; gap: .6rem; }
|
|
|
|
|
|
|
|
|
|
:global(.dp-input) { display: inline-flex; align-items: center; gap: .15rem; padding: .55rem .7rem; border-radius: 12px; border: 1px solid #334155; background: #020617; min-height: 44px; flex: 1; }
|
|
|
|
|
|
|
|
|
|
:global(.dp-seg) { display: inline-flex; align-items: center; justify-content: center; min-width: 1.7em; padding: .1rem .2rem; border-radius: 8px; outline: none; }
|
|
|
|
|
|
|
|
|
|
:global(.dp-seg[data-type="literal"]) { min-width: auto; padding: 0; color: #64748b; }
|
|
|
|
|
|
|
|
|
|
:global(.dp-seg:focus), :global(.dp-seg[data-focused]) { background: #1d4ed8; color: white; }
|
|
|
|
|
|
|
|
|
|
:global(.dp-trigger) { border: 1px solid #334155; background: #020617; color: #cbd5e1; border-radius: 10px; width: 40px; height: 40px; }
|
|
|
|
|
|
|
|
|
|
:global(.dp-popover) { background: #111827; border: 1px solid #334155; border-radius: 16px; padding: .85rem; box-shadow: 0 16px 40px rgba(0,0,0,.35); }
|
|
|
|
|
|
|
|
|
|
:global(.cal-hd) { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
|
|
|
|
|
|
|
|
|
|
:global(.cal-heading) { font-weight: 700; }
|
|
|
|
|
|
|
|
|
|
:global(.cal-btn) { border: 1px solid #334155; background: transparent; color: #cbd5e1; border-radius: 10px; width: 32px; height: 32px; }
|
|
|
|
|
|
|
|
|
|
:global(.cal-grid) { width: 100%; border-collapse: collapse; }
|
|
|
|
|
|
|
|
|
|
:global(.cal-th) { padding: .25rem; font-size: .7rem; color: #94a3b8; }
|
|
|
|
|
|
|
|
|
|
:global(.cal-td) { padding: 2px; text-align: center; }
|
|
|
|
|
|
|
|
|
|
:global(.cal-day) { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 999px; }
|
|
|
|
|
|
|
|
|
|
.two-month-layout { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }
|
|
|
|
|
|
|
|
|
|
.month-col { display: flex; flex-direction: column; gap: .4rem; }
|
|
|
|
|
|
|
|
|
|
.month-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: .35rem; }
|
|
|
|
|
|
|
|
|
|
.value { font-family: 'DM Mono', monospace; font-size: .85rem; color: #86efac; }
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|