@nomideusz/svelte-calendar 0.20.1 → 1.0.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.
- package/README.md +502 -267
- package/dist/adapters/composite.d.ts +12 -1
- package/dist/adapters/composite.js +109 -47
- package/dist/adapters/errors.d.ts +22 -0
- package/dist/adapters/errors.js +32 -0
- package/dist/adapters/index.d.ts +1 -0
- package/dist/adapters/index.js +1 -0
- package/dist/adapters/jmap.js +26 -17
- package/dist/adapters/mapped.d.ts +2 -2
- package/dist/adapters/mapped.js +18 -9
- package/dist/adapters/memory.d.ts +1 -1
- package/dist/adapters/memory.js +5 -3
- package/dist/adapters/recurring.d.ts +1 -1
- package/dist/adapters/recurring.js +43 -25
- package/dist/adapters/rest.d.ts +2 -2
- package/dist/adapters/rest.js +9 -4
- package/dist/calendar/Calendar.svelte +122 -78
- package/dist/calendar/Calendar.svelte.d.ts +69 -14
- package/dist/calendar/index.d.ts +2 -2
- package/dist/calendar/index.js +1 -1
- package/dist/core/clock.svelte.js +3 -2
- package/dist/core/locale.d.ts +11 -1
- package/dist/core/locale.js +16 -16
- package/dist/core/time.d.ts +9 -0
- package/dist/core/time.js +12 -5
- package/dist/core/timezone.d.ts +7 -3
- package/dist/core/timezone.js +10 -4
- package/dist/engine/event-store.svelte.js +94 -57
- package/dist/engine/view-state.svelte.d.ts +5 -1
- package/dist/engine/view-state.svelte.js +8 -6
- package/dist/headless/create-agenda.svelte.d.ts +8 -1
- package/dist/headless/create-agenda.svelte.js +36 -18
- package/dist/headless/create-calendar.svelte.js +57 -21
- package/dist/headless/create-range-agenda.svelte.d.ts +7 -0
- package/dist/headless/create-range-agenda.svelte.js +38 -17
- package/dist/headless/index.d.ts +1 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.js +8 -5
- package/dist/primitives/DayHeader.svelte +3 -2
- package/dist/primitives/DayHeader.svelte.d.ts +1 -1
- package/dist/primitives/EmptySlot.svelte +5 -2
- package/dist/primitives/EventBlock.svelte +21 -14
- package/dist/primitives/FloatingPanel.svelte +110 -15
- package/dist/primitives/FloatingPanel.svelte.d.ts +7 -5
- package/dist/primitives/NowIndicator.svelte +11 -4
- package/dist/primitives/TimeGutter.svelte +10 -6
- package/dist/primitives/index.d.ts +1 -0
- package/dist/text-fit.d.ts +8 -2
- package/dist/views/agenda/AgendaDay.svelte +43 -35
- package/dist/views/agenda/AgendaWeek.svelte +75 -38
- package/dist/views/index.d.ts +2 -0
- package/dist/views/index.js +2 -0
- package/dist/views/mobile/MobileDay.svelte +99 -42
- package/dist/views/mobile/MobileWeek.svelte +31 -15
- package/dist/views/mobile/swipe.js +6 -1
- package/dist/views/month/MonthGrid.svelte +33 -21
- package/dist/views/month/MonthGrid.svelte.d.ts +1 -1
- package/dist/views/planner/PlannerScroll.svelte +438 -164
- package/dist/views/planner/PlannerWeek.svelte +150 -50
- package/dist/views/shared/context.svelte.d.ts +1 -1
- package/package.json +24 -9
- package/widget/widget.js +10000 -9520
- package/dist/assets/favicon.svg +0 -9
- package/dist/widget/CalendarWidget.svelte +0 -114
- package/dist/widget/CalendarWidget.svelte.d.ts +0 -37
- package/dist/widget/index.d.ts +0 -1
- package/dist/widget/index.js +0 -1
- package/dist/widget/widget.d.ts +0 -10
- package/dist/widget/widget.js +0 -96
package/dist/assets/favicon.svg
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
2
|
-
<title>svelte-calendar</title>
|
|
3
|
-
<rect width="64" height="64" rx="16" fill="#2563eb"/>
|
|
4
|
-
<rect x="14" y="18" width="36" height="32" rx="6" fill="#fff"/>
|
|
5
|
-
<path d="M14 27h36" stroke="#2563eb" stroke-width="4"/>
|
|
6
|
-
<path d="M23 13v10M41 13v10" stroke="#fff" stroke-width="5" stroke-linecap="round"/>
|
|
7
|
-
<rect x="21" y="33" width="7" height="7" rx="2" fill="#2563eb" opacity=".9"/>
|
|
8
|
-
<rect x="36" y="33" width="7" height="7" rx="2" fill="#2563eb" opacity=".35"/>
|
|
9
|
-
</svg>
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
CalendarWidget — self-contained calendar for embedding via <day-calendar> custom element.
|
|
3
|
-
|
|
4
|
-
Accepts simple HTML attributes and wires up the full Calendar with sensible defaults.
|
|
5
|
-
Designed for non-Svelte sites (plain HTML, WordPress, Squarespace, etc.).
|
|
6
|
-
|
|
7
|
-
Usage as custom element:
|
|
8
|
-
<day-calendar
|
|
9
|
-
api="https://myschool.com/api/events"
|
|
10
|
-
theme="neutral"
|
|
11
|
-
view="week-planner"
|
|
12
|
-
height="600"
|
|
13
|
-
locale="en-US"
|
|
14
|
-
></day-calendar>
|
|
15
|
-
-->
|
|
16
|
-
<script lang="ts">import Calendar from "../calendar/Calendar.svelte";
|
|
17
|
-
import { createRestAdapter } from "../adapters/rest.js";
|
|
18
|
-
import { createMemoryAdapter } from "../adapters/memory.js";
|
|
19
|
-
import { presets } from "../theme/presets.js";
|
|
20
|
-
let { api, events, theme = "auto", view = "week-planner", height = "600", locale, dir, mondaystart = "true", headers, readonly, pills, nav, mobile, days, compact, timezone } = $props();
|
|
21
|
-
// ── Parse attributes ──
|
|
22
|
-
const heightValue = $derived.by(() => {
|
|
23
|
-
const trimmed = height.trim();
|
|
24
|
-
if (trimmed === "auto") return "auto";
|
|
25
|
-
if (/^\d+(px)?$/.test(trimmed)) return parseInt(trimmed, 10);
|
|
26
|
-
// "100%" / "50vh" aren't supported — warn instead of rendering a 100px sliver
|
|
27
|
-
console.warn(`[day-calendar] Unsupported height "${height}" — use pixels or "auto". Falling back to 600.`);
|
|
28
|
-
return 600;
|
|
29
|
-
});
|
|
30
|
-
const isMondayStart = $derived(mondaystart !== "false");
|
|
31
|
-
const themeStyle = $derived(theme in presets ? presets[theme] : presets.neutral);
|
|
32
|
-
const dirValue = $derived(dir === "rtl" || dir === "ltr" || dir === "auto" ? dir : undefined);
|
|
33
|
-
const mobileValue = $derived(mobile === "true" ? true : mobile === "false" ? false : "auto");
|
|
34
|
-
const daysValue = $derived.by(() => {
|
|
35
|
-
if (!days) return undefined;
|
|
36
|
-
const n = parseInt(days, 10);
|
|
37
|
-
return Number.isNaN(n) || n < 1 || n > 7 ? undefined : n;
|
|
38
|
-
});
|
|
39
|
-
// ── Parse static events from JSON attribute ──
|
|
40
|
-
function parseHeaders(json) {
|
|
41
|
-
if (!json) return undefined;
|
|
42
|
-
try {
|
|
43
|
-
const parsed = JSON.parse(json);
|
|
44
|
-
const out = {};
|
|
45
|
-
for (const [k, v] of Object.entries(parsed)) {
|
|
46
|
-
out[k] = String(v);
|
|
47
|
-
}
|
|
48
|
-
return out;
|
|
49
|
-
} catch {
|
|
50
|
-
console.warn("[day-calendar] Failed to parse headers JSON:", json);
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function toEvent(raw, fallbackId) {
|
|
55
|
-
const start = new Date(String(raw.start ?? ""));
|
|
56
|
-
const end = new Date(String(raw.end ?? ""));
|
|
57
|
-
if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime()) || end <= start) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
id: String(raw.id ?? fallbackId),
|
|
62
|
-
title: String(raw.title ?? "Untitled"),
|
|
63
|
-
start,
|
|
64
|
-
end,
|
|
65
|
-
color: raw.color ? String(raw.color) : undefined
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function parseEvents(json) {
|
|
69
|
-
if (!json) return [];
|
|
70
|
-
try {
|
|
71
|
-
const raw = JSON.parse(json);
|
|
72
|
-
const parsed = raw.map((e, idx) => toEvent(e, `inline-${idx}`)).filter((ev) => ev !== null);
|
|
73
|
-
if (parsed.length !== raw.length) {
|
|
74
|
-
console.warn(`[day-calendar] Ignored ${raw.length - parsed.length} invalid event(s) from events JSON.`);
|
|
75
|
-
}
|
|
76
|
-
return parsed;
|
|
77
|
-
} catch {
|
|
78
|
-
console.warn("[day-calendar] Failed to parse events JSON:", json);
|
|
79
|
-
return [];
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
// ── Create adapter ──
|
|
83
|
-
const adapter = $derived.by(() => {
|
|
84
|
-
if (api) {
|
|
85
|
-
const parsedHeaders = parseHeaders(headers);
|
|
86
|
-
return createRestAdapter({
|
|
87
|
-
baseUrl: api,
|
|
88
|
-
headers: parsedHeaders,
|
|
89
|
-
mapEvents: (data) => {
|
|
90
|
-
const arr = Array.isArray(data) ? data : data.events ?? [];
|
|
91
|
-
return arr.map((e, idx) => toEvent(e, `api-${idx}`)).filter((ev) => ev !== null);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
return createMemoryAdapter(parseEvents(events));
|
|
96
|
-
});
|
|
97
|
-
</script>
|
|
98
|
-
|
|
99
|
-
<Calendar
|
|
100
|
-
{adapter}
|
|
101
|
-
{view}
|
|
102
|
-
theme={themeStyle}
|
|
103
|
-
height={heightValue}
|
|
104
|
-
mondayStart={isMondayStart}
|
|
105
|
-
dir={dirValue}
|
|
106
|
-
{locale}
|
|
107
|
-
readOnly={readonly === 'true'}
|
|
108
|
-
showModePills={pills !== 'false'}
|
|
109
|
-
showNavigation={nav !== 'false'}
|
|
110
|
-
mobile={mobileValue}
|
|
111
|
-
days={daysValue}
|
|
112
|
-
compact={compact === 'true'}
|
|
113
|
-
timezone={timezone || undefined}
|
|
114
|
-
/>
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
interface Props {
|
|
2
|
-
/** REST API base URL — if provided, fetches events from this endpoint */
|
|
3
|
-
api?: string;
|
|
4
|
-
/** JSON string of events for static/inline data (alternative to api) */
|
|
5
|
-
events?: string;
|
|
6
|
-
/** Theme preset name: auto (default — adapts to the host page), neutral, midnight */
|
|
7
|
-
theme?: string;
|
|
8
|
-
/** Default view ID */
|
|
9
|
-
view?: string;
|
|
10
|
-
/** Calendar height: pixels (e.g. "600") or "auto" */
|
|
11
|
-
height?: string;
|
|
12
|
-
/** BCP 47 locale tag (e.g. 'en-US', 'pl-PL') */
|
|
13
|
-
locale?: string;
|
|
14
|
-
/** Text direction: ltr, rtl, auto */
|
|
15
|
-
dir?: string;
|
|
16
|
-
/** Start week on Monday (default: true) */
|
|
17
|
-
mondaystart?: string;
|
|
18
|
-
/** Custom HTTP headers as JSON string for REST adapter */
|
|
19
|
-
headers?: string;
|
|
20
|
-
/** Read-only mode: "true" disables drag/resize/create */
|
|
21
|
-
readonly?: string;
|
|
22
|
-
/** Show the Day/Week/Month pills (default: true) */
|
|
23
|
-
pills?: string;
|
|
24
|
-
/** Show prev/next/today navigation (default: true) */
|
|
25
|
-
nav?: string;
|
|
26
|
-
/** Mobile mode: "auto" (default), "true", "false" */
|
|
27
|
-
mobile?: string;
|
|
28
|
-
/** Days shown in week mode, e.g. "3" or "5" */
|
|
29
|
-
days?: string;
|
|
30
|
-
/** Compact agenda rendering: "true" */
|
|
31
|
-
compact?: string;
|
|
32
|
-
/** IANA timezone, e.g. "Europe/Warsaw" */
|
|
33
|
-
timezone?: string;
|
|
34
|
-
}
|
|
35
|
-
declare const CalendarWidget: import("svelte").Component<Props, {}, "">;
|
|
36
|
-
type CalendarWidget = ReturnType<typeof CalendarWidget>;
|
|
37
|
-
export default CalendarWidget;
|
package/dist/widget/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as CalendarWidget } from './CalendarWidget.svelte';
|
package/dist/widget/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as CalendarWidget } from './CalendarWidget.svelte';
|
package/dist/widget/widget.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
declare global {
|
|
2
|
-
/**
|
|
3
|
-
* The widget's bundled CSS, assigned at the top of widget.js by the
|
|
4
|
-
* inlineCss build plugin (vite.config.widget.ts). Undefined when this
|
|
5
|
-
* module is consumed through the normal library path (dev, SvelteKit),
|
|
6
|
-
* where styles ship through the regular Svelte CSS pipeline instead.
|
|
7
|
-
*/
|
|
8
|
-
var __DAY_CALENDAR_CSS__: string | undefined;
|
|
9
|
-
}
|
|
10
|
-
export {};
|
package/dist/widget/widget.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Widget entry point — registers <day-calendar> as a custom element.
|
|
3
|
-
*
|
|
4
|
-
* This file is the entry point for the standalone widget bundle (widget.js).
|
|
5
|
-
* Import it via a <script> tag on any HTML page.
|
|
6
|
-
*
|
|
7
|
-
* The component mounts into an open shadow root so host-page CSS (resets,
|
|
8
|
-
* theme stylesheets) cannot bleed into the calendar and calendar styles
|
|
9
|
-
* cannot leak out. The bundled CSS is injected into each shadow root — see
|
|
10
|
-
* `injectStyles` below and the inlineCss plugin in vite.config.widget.ts.
|
|
11
|
-
*/
|
|
12
|
-
import { asClassComponent } from 'svelte/legacy';
|
|
13
|
-
import CalendarWidget from './CalendarWidget.svelte';
|
|
14
|
-
const CalendarWidgetClass = asClassComponent(CalendarWidget);
|
|
15
|
-
/**
|
|
16
|
-
* Shared constructable stylesheet — parsed once, adopted by every
|
|
17
|
-
* <day-calendar> shadow root on the page.
|
|
18
|
-
*/
|
|
19
|
-
let sharedSheet = null;
|
|
20
|
-
/**
|
|
21
|
-
* Add the bundled widget CSS to a shadow root.
|
|
22
|
-
*
|
|
23
|
-
* Prefers `adoptedStyleSheets` (one parse for N widgets); falls back to a
|
|
24
|
-
* <style> element where constructable stylesheets are unavailable. No-op
|
|
25
|
-
* when the CSS global is undefined (dev / library usage).
|
|
26
|
-
*/
|
|
27
|
-
function injectStyles(root) {
|
|
28
|
-
const css = globalThis.__DAY_CALENDAR_CSS__;
|
|
29
|
-
if (!css)
|
|
30
|
-
return;
|
|
31
|
-
if ('adoptedStyleSheets' in root && typeof CSSStyleSheet !== 'undefined') {
|
|
32
|
-
try {
|
|
33
|
-
if (!sharedSheet) {
|
|
34
|
-
sharedSheet = new CSSStyleSheet();
|
|
35
|
-
sharedSheet.replaceSync(css);
|
|
36
|
-
}
|
|
37
|
-
root.adoptedStyleSheets = [...root.adoptedStyleSheets, sharedSheet];
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
// Constructable stylesheets unsupported (older engines) — fall through.
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const style = document.createElement('style');
|
|
45
|
-
style.setAttribute('data-day-calendar', '');
|
|
46
|
-
style.textContent = css;
|
|
47
|
-
root.appendChild(style);
|
|
48
|
-
}
|
|
49
|
-
const WIDGET_ATTRS = [
|
|
50
|
-
'api', 'events', 'theme', 'view', 'height', 'locale', 'dir', 'mondaystart',
|
|
51
|
-
'headers', 'readonly', 'pills', 'nav', 'mobile', 'days', 'compact', 'timezone',
|
|
52
|
-
];
|
|
53
|
-
class DayCalendarElement extends HTMLElement {
|
|
54
|
-
instance = null;
|
|
55
|
-
stylesInjected = false;
|
|
56
|
-
static get observedAttributes() {
|
|
57
|
-
return [...WIDGET_ATTRS];
|
|
58
|
-
}
|
|
59
|
-
connectedCallback() {
|
|
60
|
-
if (this.instance)
|
|
61
|
-
return;
|
|
62
|
-
// The shadow root survives disconnect/reconnect — attach only once.
|
|
63
|
-
const root = this.shadowRoot ?? this.attachShadow({ mode: 'open' });
|
|
64
|
-
if (!this.stylesInjected) {
|
|
65
|
-
injectStyles(root);
|
|
66
|
-
this.stylesInjected = true;
|
|
67
|
-
}
|
|
68
|
-
this.instance = new CalendarWidgetClass({
|
|
69
|
-
target: root,
|
|
70
|
-
props: this.readProps(),
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
disconnectedCallback() {
|
|
74
|
-
this.instance?.$destroy();
|
|
75
|
-
this.instance = null;
|
|
76
|
-
}
|
|
77
|
-
attributeChangedCallback(name, _oldValue, newValue) {
|
|
78
|
-
if (!this.instance)
|
|
79
|
-
return;
|
|
80
|
-
this.instance.$set({
|
|
81
|
-
[name]: newValue ?? undefined,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
readProps() {
|
|
85
|
-
const props = {};
|
|
86
|
-
for (const attr of WIDGET_ATTRS) {
|
|
87
|
-
const value = this.getAttribute(attr);
|
|
88
|
-
if (value !== null)
|
|
89
|
-
props[attr] = value;
|
|
90
|
-
}
|
|
91
|
-
return props;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (!customElements.get('day-calendar')) {
|
|
95
|
-
customElements.define('day-calendar', DayCalendarElement);
|
|
96
|
-
}
|