feat(ui): components, routes and styles
Sidebar (lazy tree, keyboard navigation, saved searches), page view with typed properties, tasks, tags, calendar and clip dialogs, settings with shortcut rebinding, canvas, database and board views. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0587cb267
commit
27fafa0bcd
39 files changed
+8744
-94
No files matched your search
@@ -0,0 +1,68 @@
|
||||
<script>
|
||||
import Icon from './Icon.svelte';
|
||||
import { store } from '$lib/state.svelte.js';
|
||||
|
||||
let closing = $state(false);
|
||||
const start = store.currentDay ? new Date(store.currentDay + 'T12:00:00') : new Date();
|
||||
let year = $state(start.getFullYear());
|
||||
let month = $state(start.getMonth());
|
||||
|
||||
const iso = (y, m, d) => `${y}-${String(m + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
|
||||
const now = new Date();
|
||||
const today = iso(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
const mondayFirst = $derived(store.prefs.weekStart !== 'sunday');
|
||||
const locale = $derived(store.prefs.locale || undefined);
|
||||
|
||||
let title = $derived(new Date(year, month, 1).toLocaleDateString(locale, { month: 'long', year: 'numeric' }));
|
||||
let heads = $derived(Array.from({ length: 7 }, (_, i) => new Date(2024, 0, (mondayFirst ? 1 : 7) + i).toLocaleDateString(locale, { weekday: 'short' }).slice(0, 2)));
|
||||
let cells = $derived.by(() => {
|
||||
const first = new Date(year, month, 1);
|
||||
const lead = (first.getDay() + (mondayFirst ? 6 : 0)) % 7;
|
||||
const count = new Date(year, month + 1, 0).getDate();
|
||||
const out = [];
|
||||
for (let i = 0; i < lead; i++) out.push(null);
|
||||
for (let d = 1; d <= count; d++) out.push(iso(year, month, d));
|
||||
return out;
|
||||
});
|
||||
const have = $derived(store.dailyDays);
|
||||
|
||||
function go(delta) {
|
||||
const d = new Date(year, month + delta, 1);
|
||||
year = d.getFullYear();
|
||||
month = d.getMonth();
|
||||
}
|
||||
function pick(day) {
|
||||
close();
|
||||
setTimeout(() => store.openDaily(new Date(day + 'T12:00:00')), 120);
|
||||
}
|
||||
function close() {
|
||||
closing = true;
|
||||
setTimeout(() => { store.calendarOpen = false; closing = false; }, 150);
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={(e) => e.key === 'Escape' && close()} />
|
||||
|
||||
<div class="overlay" class:closing role="presentation" onmousedown={(e) => e.target === e.currentTarget && close()}>
|
||||
<div class="panel cal-panel" role="dialog" aria-label="Daily notes calendar">
|
||||
<div class="cal-top">
|
||||
<button class="btn-icon" aria-label="Previous month" onclick={() => go(-1)}><Icon name="chevLeft" /></button>
|
||||
<b>{title}</b>
|
||||
<button class="btn-icon" aria-label="Next month" onclick={() => go(1)}><Icon name="chevRight" /></button>
|
||||
</div>
|
||||
<div class="cal-grid">
|
||||
{#each heads as h}<span class="cal-h">{h}</span>{/each}
|
||||
{#each cells as day, i (i)}
|
||||
{#if day}
|
||||
<button class="cal-d" class:today={day === today} class:has={have.has(day)} class:cur={day === store.currentDay} onclick={() => pick(day)} title={have.has(day) ? 'Open this day' : 'Create this day’s note'}>
|
||||
{Number(day.slice(8))}
|
||||
</button>
|
||||
{:else}<span></span>{/if}
|
||||
{/each}
|
||||
</div>
|
||||
<div class="cal-foot">
|
||||
<span><i class="cal-dot"></i> has a note</span>
|
||||
<button class="btn" onclick={() => pick(today)}>Today</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in new issue
Block a user