@svar-ui/svelte-calendar 2.6.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/dist/Demo.svelte +7 -0
- package/dist/Demo.svelte.d.ts +26 -0
- package/dist/components/AddEventButton.svelte +12 -0
- package/dist/components/AddEventButton.svelte.d.ts +18 -0
- package/dist/components/Calendar.svelte +110 -0
- package/dist/components/Calendar.svelte.d.ts +153 -0
- package/dist/components/CalendarPanel.svelte +147 -0
- package/dist/components/CalendarPanel.svelte.d.ts +18 -0
- package/dist/components/ContextMenu.svelte +87 -0
- package/dist/components/ContextMenu.svelte.d.ts +17 -0
- package/dist/components/DateLabel.svelte +13 -0
- package/dist/components/DateLabel.svelte.d.ts +18 -0
- package/dist/components/DateNav.svelte +31 -0
- package/dist/components/DateNav.svelte.d.ts +18 -0
- package/dist/components/DateTimePicker.svelte +30 -0
- package/dist/components/DateTimePicker.svelte.d.ts +8 -0
- package/dist/components/Editor.svelte +123 -0
- package/dist/components/Editor.svelte.d.ts +10 -0
- package/dist/components/Layout.svelte +76 -0
- package/dist/components/Layout.svelte.d.ts +21 -0
- package/dist/components/MenuButton.svelte +9 -0
- package/dist/components/MenuButton.svelte.d.ts +18 -0
- package/dist/components/Navigation.svelte +59 -0
- package/dist/components/Navigation.svelte.d.ts +12 -0
- package/dist/components/Render/BarSection.svelte +89 -0
- package/dist/components/Render/BarSection.svelte.d.ts +13 -0
- package/dist/components/Render/BoxSection.svelte +94 -0
- package/dist/components/Render/BoxSection.svelte.d.ts +15 -0
- package/dist/components/Render/Grid.svelte +16 -0
- package/dist/components/Render/Grid.svelte.d.ts +14 -0
- package/dist/components/Render/GridCells.svelte +98 -0
- package/dist/components/Render/GridCells.svelte.d.ts +14 -0
- package/dist/components/Render/GridLines.svelte +45 -0
- package/dist/components/Render/GridLines.svelte.d.ts +10 -0
- package/dist/components/Render/GridSection.svelte +348 -0
- package/dist/components/Render/GridSection.svelte.d.ts +16 -0
- package/dist/components/Render/Headers.svelte +86 -0
- package/dist/components/Render/Headers.svelte.d.ts +8 -0
- package/dist/components/Render/ListSection.svelte +110 -0
- package/dist/components/Render/ListSection.svelte.d.ts +8 -0
- package/dist/components/Render/NowLine.svelte +68 -0
- package/dist/components/Render/NowLine.svelte.d.ts +8 -0
- package/dist/components/Render/ScrollableSection.svelte +207 -0
- package/dist/components/Render/ScrollableSection.svelte.d.ts +14 -0
- package/dist/components/Render/SectionContent.svelte +83 -0
- package/dist/components/Render/SectionContent.svelte.d.ts +17 -0
- package/dist/components/Render/Sections.svelte +340 -0
- package/dist/components/Render/Sections.svelte.d.ts +14 -0
- package/dist/components/Render/YearSection.svelte +265 -0
- package/dist/components/Render/YearSection.svelte.d.ts +9 -0
- package/dist/components/Render/useEventOverlay.svelte.d.ts +21 -0
- package/dist/components/Render/useEventOverlay.svelte.js +60 -0
- package/dist/components/TodayButton.svelte +11 -0
- package/dist/components/TodayButton.svelte.d.ts +18 -0
- package/dist/components/editorItems.d.ts +15 -0
- package/dist/components/editorItems.js +20 -0
- package/dist/components/types.d.ts +29 -0
- package/dist/components/types.js +1 -0
- package/dist/directives/clickdate.d.ts +8 -0
- package/dist/directives/clickdate.js +45 -0
- package/dist/directives/clickevent.d.ts +15 -0
- package/dist/directives/clickevent.js +54 -0
- package/dist/directives/drag.d.ts +19 -0
- package/dist/directives/drag.js +494 -0
- package/dist/directives/dragresize.d.ts +10 -0
- package/dist/directives/dragresize.js +58 -0
- package/dist/directives/resize.d.ts +5 -0
- package/dist/directives/resize.js +11 -0
- package/dist/dom.d.ts +1 -0
- package/dist/dom.js +12 -0
- package/dist/env.d.ts +9 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +12 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +5 -0
- package/dist/themes/Willow.svelte +16 -0
- package/dist/themes/Willow.svelte.d.ts +7 -0
- package/dist/themes/WillowDark.svelte +16 -0
- package/dist/themes/WillowDark.svelte.d.ts +7 -0
- package/license.txt +21 -0
- package/package.json +60 -0
- package/readme.md +107 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script lang="ts">const { xHeaders, yHeaders, dx, dy, cellCss, view, section, mode } = $props();
|
|
2
|
+
function getDate(unit) {
|
|
3
|
+
return unit?.ui?.date instanceof Date ? unit.ui.date : null;
|
|
4
|
+
}
|
|
5
|
+
function combineDates(dateUnit, timeUnit) {
|
|
6
|
+
const d = new Date(dateUnit);
|
|
7
|
+
d.setHours(timeUnit.getHours(), timeUnit.getMinutes(), timeUnit.getSeconds(), 0);
|
|
8
|
+
return d;
|
|
9
|
+
}
|
|
10
|
+
function resolveDate(x, y) {
|
|
11
|
+
const xd = getDate(x);
|
|
12
|
+
const yd = getDate(y);
|
|
13
|
+
if (xd && yd) return combineDates(xd, yd);
|
|
14
|
+
return xd ?? yd;
|
|
15
|
+
}
|
|
16
|
+
const cells = $derived.by(() => {
|
|
17
|
+
const xUnits = xHeaders ? xHeaders[xHeaders.length - 1] : null;
|
|
18
|
+
const yUnits = yHeaders ? yHeaders[yHeaders.length - 1] : null;
|
|
19
|
+
const result = [];
|
|
20
|
+
const computeCss = cellCss ? (x, y) => cellCss({
|
|
21
|
+
view,
|
|
22
|
+
section,
|
|
23
|
+
mode,
|
|
24
|
+
x,
|
|
25
|
+
y,
|
|
26
|
+
date: resolveDate(x, y)
|
|
27
|
+
}) : () => "";
|
|
28
|
+
if (xUnits && yUnits) {
|
|
29
|
+
for (const xUnit of xUnits) {
|
|
30
|
+
for (const yUnit of yUnits) {
|
|
31
|
+
result.push({
|
|
32
|
+
x: xUnit.position,
|
|
33
|
+
y: yUnit.position,
|
|
34
|
+
width: xUnit.size,
|
|
35
|
+
height: yUnit.size,
|
|
36
|
+
css: computeCss(xUnit, yUnit),
|
|
37
|
+
weekend: !!(xUnit.weekend || yUnit.weekend)
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} else if (xUnits) {
|
|
42
|
+
for (const xUnit of xUnits) {
|
|
43
|
+
result.push({
|
|
44
|
+
x: xUnit.position,
|
|
45
|
+
y: 0,
|
|
46
|
+
width: xUnit.size,
|
|
47
|
+
height: 100,
|
|
48
|
+
css: computeCss(xUnit, null),
|
|
49
|
+
weekend: !!xUnit.weekend
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
} else if (yUnits) {
|
|
53
|
+
for (const yUnit of yUnits) {
|
|
54
|
+
result.push({
|
|
55
|
+
x: 0,
|
|
56
|
+
y: yUnit.position,
|
|
57
|
+
width: 100,
|
|
58
|
+
height: yUnit.size,
|
|
59
|
+
css: computeCss(null, yUnit),
|
|
60
|
+
weekend: !!yUnit.weekend
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
});
|
|
66
|
+
function cellStyle(c) {
|
|
67
|
+
return `left:${dx * c.x}px;top:${dy * c.y}px;width:${dx * c.width}px;height:${dy * c.height}px`;
|
|
68
|
+
}
|
|
69
|
+
export {};
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<div class="wx-grid" aria-hidden="true">
|
|
73
|
+
{#each cells as c}
|
|
74
|
+
<div
|
|
75
|
+
class="wx-grid-cell {c.css}"
|
|
76
|
+
class:wx-weekend={c.weekend}
|
|
77
|
+
style={cellStyle(c)}
|
|
78
|
+
></div>
|
|
79
|
+
{/each}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<style>
|
|
83
|
+
.wx-grid {
|
|
84
|
+
position: absolute;
|
|
85
|
+
inset: 0;
|
|
86
|
+
pointer-events: none;
|
|
87
|
+
z-index: 0;
|
|
88
|
+
}
|
|
89
|
+
.wx-grid-cell {
|
|
90
|
+
position: absolute;
|
|
91
|
+
box-sizing: border-box;
|
|
92
|
+
border-right: var(--wx-border);
|
|
93
|
+
border-bottom: var(--wx-border);
|
|
94
|
+
}
|
|
95
|
+
.wx-grid-cell.wx-weekend {
|
|
96
|
+
background-color: var(--wx-calendar-weekend-background);
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CellCss, ScaleUnit, SectionMode } from "@svar-ui/calendar-store";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
xHeaders: ScaleUnit[][] | null;
|
|
4
|
+
yHeaders: ScaleUnit[][] | null;
|
|
5
|
+
dx: number;
|
|
6
|
+
dy: number;
|
|
7
|
+
cellCss?: CellCss;
|
|
8
|
+
view: string;
|
|
9
|
+
section: string;
|
|
10
|
+
mode: SectionMode;
|
|
11
|
+
};
|
|
12
|
+
declare const GridCells: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
|
+
type GridCells = ReturnType<typeof GridCells>;
|
|
14
|
+
export default GridCells;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">const { xHeaders, yHeaders, dx, dy } = $props();
|
|
2
|
+
export {};
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="wx-grid" aria-hidden="true">
|
|
6
|
+
{#if xHeaders}
|
|
7
|
+
{#each xHeaders[xHeaders.length - 1].slice(0, -1) as unit}
|
|
8
|
+
<div
|
|
9
|
+
class="wx-grid-line wx-vertical"
|
|
10
|
+
style="left: {dx * (unit.position + unit.size)}px"
|
|
11
|
+
></div>
|
|
12
|
+
{/each}
|
|
13
|
+
{/if}
|
|
14
|
+
{#if yHeaders}
|
|
15
|
+
{#each yHeaders[yHeaders.length - 1].slice(0, -1) as unit}
|
|
16
|
+
<div
|
|
17
|
+
class="wx-grid-line wx-horizontal"
|
|
18
|
+
style="top: {dy * (unit.position + unit.size)}px"
|
|
19
|
+
></div>
|
|
20
|
+
{/each}
|
|
21
|
+
{/if}
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<style>
|
|
25
|
+
.wx-grid {
|
|
26
|
+
position: absolute;
|
|
27
|
+
inset: 0;
|
|
28
|
+
pointer-events: none;
|
|
29
|
+
z-index: 0;
|
|
30
|
+
}
|
|
31
|
+
.wx-grid-line {
|
|
32
|
+
position: absolute;
|
|
33
|
+
background-color: var(--wx-calendar-grid-color);
|
|
34
|
+
}
|
|
35
|
+
.wx-grid-line.wx-vertical {
|
|
36
|
+
top: 0;
|
|
37
|
+
width: 1px;
|
|
38
|
+
height: 100%;
|
|
39
|
+
}
|
|
40
|
+
.wx-grid-line.wx-horizontal {
|
|
41
|
+
left: 0;
|
|
42
|
+
height: 1px;
|
|
43
|
+
width: 100%;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ScaleUnit } from "@svar-ui/calendar-store";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
xHeaders: ScaleUnit[][] | null;
|
|
4
|
+
yHeaders: ScaleUnit[][] | null;
|
|
5
|
+
dx: number;
|
|
6
|
+
dy: number;
|
|
7
|
+
};
|
|
8
|
+
declare const GridLines: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type GridLines = ReturnType<typeof GridLines>;
|
|
10
|
+
export default GridLines;
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
<script lang="ts">import { setID } from "@svar-ui/lib-dom";
|
|
2
|
+
const { primitives, cells, dx, dy, cellCss, eventCss, eventContent, view, section, onoverflow } = $props();
|
|
3
|
+
const laneHeight = 22;
|
|
4
|
+
const gap = 2;
|
|
5
|
+
const fullLaneHeight = laneHeight + gap * 2;
|
|
6
|
+
const dayLabelHeight = 20;
|
|
7
|
+
const moreLabelHeight = 18;
|
|
8
|
+
// Track which rows (by y position) are expanded
|
|
9
|
+
let expandedRows = $state(new Set());
|
|
10
|
+
// Compute per-row: max visible lanes and extra offset for expanded rows
|
|
11
|
+
const rowLayout = $derived.by(() => {
|
|
12
|
+
// Collect per-row max lane counts
|
|
13
|
+
const rowInfo = new Map();
|
|
14
|
+
for (const p of primitives) {
|
|
15
|
+
const existing = rowInfo.get(p.y);
|
|
16
|
+
const lanes = p.totalLanes ?? 1;
|
|
17
|
+
if (!existing || lanes > existing.totalLanes) {
|
|
18
|
+
rowInfo.set(p.y, {
|
|
19
|
+
totalLanes: lanes,
|
|
20
|
+
height: p.height
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const layout = new Map();
|
|
25
|
+
for (const [y, info] of rowInfo) {
|
|
26
|
+
const groupHeight = dy * info.height - dayLabelHeight;
|
|
27
|
+
// Only reserve space for "+more" label if lanes don't all fit
|
|
28
|
+
const allFit = Math.floor(groupHeight / fullLaneHeight) >= info.totalLanes;
|
|
29
|
+
const maxVisible = allFit ? info.totalLanes : Math.max(0, Math.floor((groupHeight - moreLabelHeight) / fullLaneHeight));
|
|
30
|
+
const isExpanded = expandedRows.has(y);
|
|
31
|
+
let extraHeight = 0;
|
|
32
|
+
if (isExpanded && info.totalLanes > maxVisible) {
|
|
33
|
+
// Extra pixels needed beyond the normal row height
|
|
34
|
+
const neededHeight = dayLabelHeight + info.totalLanes * fullLaneHeight;
|
|
35
|
+
const normalHeight = dy * info.height;
|
|
36
|
+
extraHeight = Math.max(0, neededHeight - normalHeight);
|
|
37
|
+
}
|
|
38
|
+
layout.set(y, {
|
|
39
|
+
maxVisible,
|
|
40
|
+
expanded: isExpanded,
|
|
41
|
+
extraHeight
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return layout;
|
|
45
|
+
});
|
|
46
|
+
// Cumulative extra offset per row — sorted by y position
|
|
47
|
+
const rowExtraOffsets = $derived.by(() => {
|
|
48
|
+
const offsets = new Map();
|
|
49
|
+
const sorted = [...rowLayout.entries()].sort((a, b) => a[0] - b[0]);
|
|
50
|
+
let cumulative = 0;
|
|
51
|
+
for (const [y, info] of sorted) {
|
|
52
|
+
offsets.set(y, cumulative);
|
|
53
|
+
cumulative += info.extraHeight;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
offsets,
|
|
57
|
+
totalExtra: cumulative
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
function getRowOffset(y) {
|
|
61
|
+
return rowExtraOffsets.offsets.get(y) ?? 0;
|
|
62
|
+
}
|
|
63
|
+
// Total height — only set when rows are expanded to avoid sub-pixel overflow
|
|
64
|
+
const totalExtra = $derived(rowExtraOffsets.totalExtra);
|
|
65
|
+
const totalHeight = $derived(totalExtra > 0 ? dy * 100 + totalExtra : null);
|
|
66
|
+
const hasOverflow = $derived(totalExtra > 0);
|
|
67
|
+
$effect(() => {
|
|
68
|
+
onoverflow?.(hasOverflow);
|
|
69
|
+
});
|
|
70
|
+
// Partition primitives into visible and hidden-by-row in one pass
|
|
71
|
+
const { visiblePrimitives, hiddenByRow } = $derived.by(() => {
|
|
72
|
+
const visible = [];
|
|
73
|
+
const hidden = new Map();
|
|
74
|
+
for (const p of primitives) {
|
|
75
|
+
const info = rowLayout.get(p.y);
|
|
76
|
+
if (!info || info.expanded || (p.lane ?? 0) < info.maxVisible) {
|
|
77
|
+
visible.push(p);
|
|
78
|
+
} else {
|
|
79
|
+
let arr = hidden.get(p.y);
|
|
80
|
+
if (!arr) {
|
|
81
|
+
arr = [];
|
|
82
|
+
hidden.set(p.y, arr);
|
|
83
|
+
}
|
|
84
|
+
arr.push(p);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
visiblePrimitives: visible,
|
|
89
|
+
hiddenByRow: hidden
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
// Per-cell "+N more" indicators
|
|
93
|
+
const moreIndicators = $derived.by(() => {
|
|
94
|
+
const indicators = [];
|
|
95
|
+
for (const cell of cells) {
|
|
96
|
+
const hidden = hiddenByRow.get(cell.y);
|
|
97
|
+
if (!hidden) continue;
|
|
98
|
+
let count = 0;
|
|
99
|
+
for (const p of hidden) {
|
|
100
|
+
if (p.x < cell.x + cell.width && p.x + p.width > cell.x) {
|
|
101
|
+
count++;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (count > 0) {
|
|
105
|
+
indicators.push({
|
|
106
|
+
rowY: cell.y,
|
|
107
|
+
cellX: cell.x,
|
|
108
|
+
cellWidth: cell.width,
|
|
109
|
+
count
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return indicators;
|
|
114
|
+
});
|
|
115
|
+
function barStyle(p) {
|
|
116
|
+
const left = dx * p.x + gap;
|
|
117
|
+
const width = dx * p.width - gap * 2;
|
|
118
|
+
const lane = p.lane ?? 0;
|
|
119
|
+
const groupTop = dy * p.y + dayLabelHeight + getRowOffset(p.y);
|
|
120
|
+
const top = groupTop + lane * fullLaneHeight + gap;
|
|
121
|
+
const height = laneHeight;
|
|
122
|
+
return `left:${left}px;top:${top}px;width:${width}px;height:${height}px`;
|
|
123
|
+
}
|
|
124
|
+
function formatTime(date) {
|
|
125
|
+
const h = date.getHours();
|
|
126
|
+
const m = date.getMinutes();
|
|
127
|
+
if (m === 0) return `${h % 12 || 12}${h < 12 ? "am" : "pm"}`;
|
|
128
|
+
return `${h % 12 || 12}:${String(m).padStart(2, "0")}${h < 12 ? "am" : "pm"}`;
|
|
129
|
+
}
|
|
130
|
+
function eventLabel(p) {
|
|
131
|
+
return p.event.text || " ";
|
|
132
|
+
}
|
|
133
|
+
function eventTime(p) {
|
|
134
|
+
if (p.isMultiDay === false) {
|
|
135
|
+
return `${formatTime(p.event.start)} `;
|
|
136
|
+
}
|
|
137
|
+
return "";
|
|
138
|
+
}
|
|
139
|
+
function dateStr(date) {
|
|
140
|
+
const y = date.getFullYear();
|
|
141
|
+
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
142
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
143
|
+
return `${y}-${m}-${d}`;
|
|
144
|
+
}
|
|
145
|
+
function css(p) {
|
|
146
|
+
const base = p.event.css || "";
|
|
147
|
+
const dynamic = eventCss ? eventCss({
|
|
148
|
+
event: p.event,
|
|
149
|
+
view,
|
|
150
|
+
section,
|
|
151
|
+
mode: "grid"
|
|
152
|
+
}) : "";
|
|
153
|
+
return base + (dynamic ? " " + dynamic : "");
|
|
154
|
+
}
|
|
155
|
+
function cellStyle(cell) {
|
|
156
|
+
const offset = getRowOffset(cell.y);
|
|
157
|
+
const info = rowLayout.get(cell.y);
|
|
158
|
+
const extra = info?.extraHeight ?? 0;
|
|
159
|
+
const left = dx * cell.x;
|
|
160
|
+
const top = dy * cell.y + offset;
|
|
161
|
+
const width = dx * cell.width;
|
|
162
|
+
const height = dy * cell.height + extra;
|
|
163
|
+
return `left:${left}px;top:${top}px;width:${width}px;height:${height}px`;
|
|
164
|
+
}
|
|
165
|
+
function moreStyle(indicator) {
|
|
166
|
+
const offset = getRowOffset(indicator.rowY);
|
|
167
|
+
const info = rowLayout.get(indicator.rowY);
|
|
168
|
+
const top = dy * indicator.rowY + dayLabelHeight + offset + info.maxVisible * fullLaneHeight;
|
|
169
|
+
const left = dx * indicator.cellX;
|
|
170
|
+
const width = dx * indicator.cellWidth;
|
|
171
|
+
return `left:${left}px;top:${top}px;width:${width}px;height:${moreLabelHeight}px`;
|
|
172
|
+
}
|
|
173
|
+
function toggleRow(y) {
|
|
174
|
+
const next = new Set(expandedRows);
|
|
175
|
+
if (next.has(y)) {
|
|
176
|
+
next.delete(y);
|
|
177
|
+
} else {
|
|
178
|
+
next.add(y);
|
|
179
|
+
}
|
|
180
|
+
expandedRows = next;
|
|
181
|
+
}
|
|
182
|
+
</script>
|
|
183
|
+
|
|
184
|
+
<div
|
|
185
|
+
class="wx-grid-section"
|
|
186
|
+
style:height={totalHeight !== null ? `${totalHeight}px` : undefined}
|
|
187
|
+
>
|
|
188
|
+
{#each cells as cell}
|
|
189
|
+
<div
|
|
190
|
+
class="wx-grid-cell {cellCss
|
|
191
|
+
? cellCss({
|
|
192
|
+
view,
|
|
193
|
+
section,
|
|
194
|
+
mode: 'grid',
|
|
195
|
+
x: null,
|
|
196
|
+
y: null,
|
|
197
|
+
date: cell.date,
|
|
198
|
+
})
|
|
199
|
+
: ''}"
|
|
200
|
+
class:wx-weekend={cell.weekend}
|
|
201
|
+
class:wx-out-of-month={!cell.inMonth}
|
|
202
|
+
class:wx-today={cell.today}
|
|
203
|
+
aria-current={cell.today ? "date" : undefined}
|
|
204
|
+
style={cellStyle(cell)}
|
|
205
|
+
>
|
|
206
|
+
<span class="wx-day-number" data-date={dateStr(cell.date)}
|
|
207
|
+
>{cell.day}</span
|
|
208
|
+
>
|
|
209
|
+
</div>
|
|
210
|
+
{/each}
|
|
211
|
+
|
|
212
|
+
{#each visiblePrimitives as p (p.id)}
|
|
213
|
+
<div
|
|
214
|
+
class="wx-bar-event {css(p)}"
|
|
215
|
+
class:wx-bar-single-day={p.isMultiDay === false}
|
|
216
|
+
style={barStyle(p)}
|
|
217
|
+
data-id={setID(p.id)}
|
|
218
|
+
>
|
|
219
|
+
{#if eventContent}
|
|
220
|
+
{@const EventContentCmp = eventContent}
|
|
221
|
+
<EventContentCmp event={p.event} mode="grid" />
|
|
222
|
+
{:else}
|
|
223
|
+
<span class="wx-bar-marker"></span>
|
|
224
|
+
<span class="wx-bar-time">{eventTime(p)}</span>
|
|
225
|
+
<span class="wx-bar-title">{eventLabel(p)}</span>
|
|
226
|
+
{/if}
|
|
227
|
+
</div>
|
|
228
|
+
{/each}
|
|
229
|
+
|
|
230
|
+
{#each moreIndicators as indicator}
|
|
231
|
+
<button
|
|
232
|
+
class="wx-more-button"
|
|
233
|
+
style={moreStyle(indicator)}
|
|
234
|
+
onclick={() => toggleRow(indicator.rowY)}
|
|
235
|
+
>
|
|
236
|
+
+{indicator.count} more
|
|
237
|
+
</button>
|
|
238
|
+
{/each}
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
<style>
|
|
242
|
+
.wx-grid-section {
|
|
243
|
+
position: relative;
|
|
244
|
+
width: 100%;
|
|
245
|
+
height: 100%;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.wx-grid-cell {
|
|
249
|
+
position: absolute;
|
|
250
|
+
box-sizing: border-box;
|
|
251
|
+
border-right: var(--wx-border);
|
|
252
|
+
border-bottom: var(--wx-border);
|
|
253
|
+
}
|
|
254
|
+
.wx-grid-cell.wx-weekend {
|
|
255
|
+
background-color: var(--wx-calendar-weekend-background);
|
|
256
|
+
}
|
|
257
|
+
.wx-grid-cell.wx-out-of-month {
|
|
258
|
+
background-color: var(--wx-background-alt);
|
|
259
|
+
}
|
|
260
|
+
.wx-grid-cell.wx-today {
|
|
261
|
+
background-color: var(--wx-color-primary-selected);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.wx-day-number {
|
|
265
|
+
display: block;
|
|
266
|
+
padding: 2px 4px;
|
|
267
|
+
font-size: var(--wx-font-size-sm);
|
|
268
|
+
text-align: right;
|
|
269
|
+
cursor: pointer;
|
|
270
|
+
}
|
|
271
|
+
.wx-out-of-month .wx-day-number {
|
|
272
|
+
color: var(--wx-color-font-alt);
|
|
273
|
+
}
|
|
274
|
+
.wx-today .wx-day-number {
|
|
275
|
+
font-weight: var(--wx-font-weight-b);
|
|
276
|
+
color: var(--wx-color-primary);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.wx-bar-event {
|
|
280
|
+
position: absolute;
|
|
281
|
+
background-color: var(--wx-color-primary);
|
|
282
|
+
color: var(--wx-color-primary-font);
|
|
283
|
+
border-radius: var(--wx-border-radius);
|
|
284
|
+
overflow: hidden;
|
|
285
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
|
286
|
+
cursor: pointer;
|
|
287
|
+
display: flex;
|
|
288
|
+
align-items: center;
|
|
289
|
+
z-index: 1;
|
|
290
|
+
}
|
|
291
|
+
.wx-bar-event:hover {
|
|
292
|
+
opacity: 0.9;
|
|
293
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
|
|
294
|
+
}
|
|
295
|
+
.wx-bar-single-day {
|
|
296
|
+
background-color: transparent;
|
|
297
|
+
color: var(--wx-color-font);
|
|
298
|
+
box-shadow: none;
|
|
299
|
+
border-radius: 0;
|
|
300
|
+
}
|
|
301
|
+
.wx-bar-single-day:hover {
|
|
302
|
+
background-color: var(--wx-color-secondary-hover);
|
|
303
|
+
box-shadow: none;
|
|
304
|
+
opacity: 1;
|
|
305
|
+
}
|
|
306
|
+
.wx-bar-title {
|
|
307
|
+
padding: 0 6px;
|
|
308
|
+
white-space: nowrap;
|
|
309
|
+
overflow: hidden;
|
|
310
|
+
text-overflow: ellipsis;
|
|
311
|
+
font-size: 12px;
|
|
312
|
+
line-height: 1.2;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.wx-more-button {
|
|
316
|
+
position: absolute;
|
|
317
|
+
background: none;
|
|
318
|
+
border: none;
|
|
319
|
+
box-sizing: border-box;
|
|
320
|
+
padding: 0 4px;
|
|
321
|
+
font-size: 12px;
|
|
322
|
+
color: var(--wx-color-link, var(--wx-color-primary));
|
|
323
|
+
cursor: pointer;
|
|
324
|
+
z-index: 2;
|
|
325
|
+
text-align: left;
|
|
326
|
+
line-height: 18px;
|
|
327
|
+
}
|
|
328
|
+
.wx-more-button:hover {
|
|
329
|
+
text-decoration: underline;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.wx-bar-time {
|
|
333
|
+
font-weight: var(--wx-font-weight-md);
|
|
334
|
+
font-size: 12px;
|
|
335
|
+
margin-bottom: 1px;
|
|
336
|
+
margin-left: 4px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.wx-bar-marker {
|
|
340
|
+
display: block;
|
|
341
|
+
width: 6px;
|
|
342
|
+
height: 6px;
|
|
343
|
+
border-radius: 50%;
|
|
344
|
+
background-color: var(--wx-color-primary);
|
|
345
|
+
margin-bottom: 1px;
|
|
346
|
+
margin-left: 4px;
|
|
347
|
+
}
|
|
348
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Primitive, GridCell, CellCss, EventCss } from "@svar-ui/calendar-store";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
primitives: Primitive[];
|
|
4
|
+
cells: GridCell[];
|
|
5
|
+
dx: number;
|
|
6
|
+
dy: number;
|
|
7
|
+
cellCss?: CellCss;
|
|
8
|
+
eventCss?: EventCss;
|
|
9
|
+
eventContent?: any;
|
|
10
|
+
view: string;
|
|
11
|
+
section: string;
|
|
12
|
+
onoverflow?: (overflow: boolean) => void;
|
|
13
|
+
};
|
|
14
|
+
declare const GridSection: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
15
|
+
type GridSection = ReturnType<typeof GridSection>;
|
|
16
|
+
export default GridSection;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script lang="ts">const { headers, direction } = $props();
|
|
2
|
+
export {};
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
{#if direction === "x"}
|
|
6
|
+
<div class="wx-x-headers">
|
|
7
|
+
{#each headers as level}
|
|
8
|
+
<div class="wx-x-header-row">
|
|
9
|
+
{#each level as unit}
|
|
10
|
+
<div
|
|
11
|
+
class="wx-x-header-cell"
|
|
12
|
+
role="columnheader"
|
|
13
|
+
style="left:{unit.position}%;width:{unit.size}%"
|
|
14
|
+
>
|
|
15
|
+
{unit.label}
|
|
16
|
+
</div>
|
|
17
|
+
{/each}
|
|
18
|
+
</div>
|
|
19
|
+
{/each}
|
|
20
|
+
</div>
|
|
21
|
+
{:else}
|
|
22
|
+
<div class="wx-y-headers">
|
|
23
|
+
{#each headers as level}
|
|
24
|
+
<div class="wx-y-header-col">
|
|
25
|
+
{#each level as unit}
|
|
26
|
+
<div
|
|
27
|
+
class="wx-y-header-cell"
|
|
28
|
+
role="rowheader"
|
|
29
|
+
style="top:{unit.position}%;height:{unit.size}%"
|
|
30
|
+
>
|
|
31
|
+
{unit.label}
|
|
32
|
+
</div>
|
|
33
|
+
{/each}
|
|
34
|
+
</div>
|
|
35
|
+
{/each}
|
|
36
|
+
</div>
|
|
37
|
+
{/if}
|
|
38
|
+
|
|
39
|
+
<style>
|
|
40
|
+
.wx-x-headers {
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
border-bottom: var(--wx-border);
|
|
43
|
+
}
|
|
44
|
+
.wx-x-header-row {
|
|
45
|
+
position: relative;
|
|
46
|
+
display: flex;
|
|
47
|
+
height: 32px;
|
|
48
|
+
}
|
|
49
|
+
.wx-x-header-cell {
|
|
50
|
+
position: absolute;
|
|
51
|
+
height: 100%;
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
justify-content: center;
|
|
55
|
+
font-size: 13px;
|
|
56
|
+
font-weight: 500;
|
|
57
|
+
border-right: var(--wx-border);
|
|
58
|
+
}
|
|
59
|
+
.wx-x-header-cell:last-child {
|
|
60
|
+
border-right: none;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.wx-y-headers {
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-shrink: 0;
|
|
66
|
+
width: var(--wx-calendar-y-scale-width, 60px);
|
|
67
|
+
height: 100%;
|
|
68
|
+
border-right: var(--wx-border);
|
|
69
|
+
}
|
|
70
|
+
.wx-y-header-col {
|
|
71
|
+
position: relative;
|
|
72
|
+
flex: 1;
|
|
73
|
+
min-width: 0;
|
|
74
|
+
height: 100%;
|
|
75
|
+
}
|
|
76
|
+
.wx-y-header-cell {
|
|
77
|
+
position: absolute;
|
|
78
|
+
width: 100%;
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: flex-start;
|
|
81
|
+
justify-content: center;
|
|
82
|
+
font-size: 11px;
|
|
83
|
+
color: var(--wx-color-font-alt);
|
|
84
|
+
padding-top: 2px;
|
|
85
|
+
}
|
|
86
|
+
</style>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ScaleUnit } from "@svar-ui/calendar-store";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
headers: ScaleUnit[][];
|
|
4
|
+
direction: "x" | "y";
|
|
5
|
+
};
|
|
6
|
+
declare const Headers: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Headers = ReturnType<typeof Headers>;
|
|
8
|
+
export default Headers;
|