@jungherz-de/notionkit-elements 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,65 @@
1
+ // Calendar days for nk-calendar and nk-calendar-view: local days as
2
+ // 'YYYY-MM-DD', no library. Weeks are ISO weeks (Monday-based, the week with
3
+ // the year's first Thursday); the first weekday comes from the locale.
4
+ const pad = n => String(n).padStart(2, '0');
5
+
6
+ export const isoOf = d => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
7
+ export const addDays = (d, n) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);
8
+
9
+ /** 'YYYY-MM-DD[THH:MM]', 'D.M.YYYY', a Date or { start } → a local Date at midnight, or null. */
10
+ export function parseDay(v) {
11
+ if (v instanceof Date) return Number.isNaN(v.getTime()) ? null : new Date(v.getFullYear(), v.getMonth(), v.getDate());
12
+ if (v && typeof v === 'object') return v.start ? parseDay(v.start) : null;
13
+ const s = String(v ?? '').trim();
14
+ let m = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
15
+ if (m) return new Date(+m[1], +m[2] - 1, +m[3]);
16
+ m = s.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/);
17
+ return m ? new Date(+m[3], +m[2] - 1, +m[1]) : null;
18
+ }
19
+
20
+ export function isoWeek(d) {
21
+ const t = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
22
+ t.setUTCDate(t.getUTCDate() + 4 - (t.getUTCDay() || 7));
23
+ return Math.ceil(((t - Date.UTC(t.getUTCFullYear(), 0, 1)) / 864e5 + 1) / 7);
24
+ }
25
+
26
+ /** The page's language unless the element names one. */
27
+ export const resolveLocale = attr => attr || document.documentElement.lang || navigator.language || 'en';
28
+
29
+ /** 0 = Sunday … 6 = Saturday, from Intl.Locale's week info; Monday where the browser cannot say. */
30
+ export function firstWeekday(locale) {
31
+ try {
32
+ const l = new Intl.Locale(locale), info = l.getWeekInfo?.() ?? l.weekInfo;
33
+ if (info?.firstDay) return info.firstDay % 7;
34
+ } catch { /* an unknown tag */ }
35
+ return 1;
36
+ }
37
+
38
+ /** Short weekday names from `weekStart` on; `length` cuts them (2 → "Mo"). */
39
+ export function weekdayNames(locale, weekStart, length = 0) {
40
+ const f = new Intl.DateTimeFormat(locale, { weekday: 'short' });
41
+ // 7 June 2026 is a Sunday, so 7 + n is weekday n.
42
+ return Array.from({ length: 7 }, (_, i) => {
43
+ const name = f.format(new Date(2026, 5, 7 + ((weekStart + i) % 7))).replace('.', '');
44
+ return length ? name.slice(0, length) : name;
45
+ });
46
+ }
47
+
48
+ /** A month from its week start: `first`, `day(i)` for the i-th cell, the `rows` it needs. */
49
+ export function monthGrid(month, weekStart) {
50
+ const [y, m] = month.split('-').map(Number), first = new Date(y, m - 1, 1), offset = (first.getDay() - weekStart + 7) % 7;
51
+ return { m, first, day: i => new Date(y, m - 1, 1 - offset + i), rows: Math.ceil((offset + new Date(y, m, 0).getDate()) / 7) };
52
+ }
53
+
54
+ export function stepMonth(month, n) {
55
+ const [y, m] = month.split('-').map(Number);
56
+ return isoOf(new Date(y, m - 1 + n, 1)).slice(0, 7);
57
+ }
58
+
59
+ /** "KW" for German, "W" elsewhere – the head of the week column. */
60
+ export const weekLabel = locale => (/^de\b/i.test(locale) ? 'KW' : 'W');
61
+
62
+ export const CHEVRONS = {
63
+ prev: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg>',
64
+ next: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg>',
65
+ };
@@ -0,0 +1,20 @@
1
+ // Placement for elements that float over the page – <nk-menu floating>,
2
+ // <nk-calendar floating>: the host is a fixed box put under its anchor.
3
+
4
+ /** The border box of an element, or of the first descendant with one (display: contents hosts). */
5
+ export function boxOf(el) {
6
+ if (el.getClientRects().length) return el.getBoundingClientRect();
7
+ for (const child of [...(el.shadowRoot?.children ?? []), ...el.children]) {
8
+ const r = boxOf(child);
9
+ if (r.width || r.height) return r;
10
+ }
11
+ return el.getBoundingClientRect();
12
+ }
13
+
14
+ /** Puts `host` 6px under `anchor`, right edges aligned – left edges with align="start". */
15
+ export function placeUnder(host, anchor, align) {
16
+ const r = boxOf(anchor);
17
+ host.style.top = `${r.bottom + 6}px`;
18
+ if (align === 'start') { host.style.left = `${r.left}px`; host.style.right = ''; }
19
+ else { host.style.right = `${Math.max(8, innerWidth - r.right)}px`; host.style.left = ''; }
20
+ }