@bimetal/calendar-svelte-components 0.29.0 → 0.32.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/components/Calendar.svelte +64 -31
- package/dist/components/Calendar.svelte.d.ts +14 -2
- package/dist/components/Calendar.svelte.d.ts.map +1 -1
- package/dist/components/CalendarHeader.svelte +10 -10
- package/dist/components/CategoryFilter.svelte +2 -2
- package/dist/components/EventBar.svelte +16 -12
- package/dist/components/EventBar.svelte.d.ts.map +1 -1
- package/dist/components/EventDialog.svelte +50 -50
- package/dist/components/EventHistory.svelte +17 -21
- package/dist/components/EventHistory.svelte.d.ts.map +1 -1
- package/dist/components/ResourceFilter.svelte +2 -2
- package/dist/components/UndoToast.svelte +5 -5
- package/dist/views/agenda/AgendaEvent.svelte +14 -13
- package/dist/views/agenda/AgendaEvent.svelte.d.ts +2 -1
- package/dist/views/agenda/AgendaEvent.svelte.d.ts.map +1 -1
- package/dist/views/agenda/AgendaView.svelte +57 -115
- package/dist/views/agenda/AgendaView.svelte.d.ts +3 -2
- package/dist/views/agenda/AgendaView.svelte.d.ts.map +1 -1
- package/dist/views/day/AllDayEvent.svelte +1 -1
- package/dist/views/day/DayView.svelte +16 -16
- package/dist/views/month/MonthView.svelte +4 -4
- package/dist/views/month/TimedEntry.svelte +10 -4
- package/dist/views/month/TimedEntry.svelte.d.ts.map +1 -1
- package/dist/views/month/WeekRow.svelte +13 -13
- package/dist/views/resource/ResourceView.svelte +18 -18
- package/dist/views/timeline/TimelineView.svelte +13 -13
- package/dist/views/week/AllDayRow.svelte +3 -3
- package/dist/views/week/TimeEvent.svelte +18 -7
- package/dist/views/week/TimeEvent.svelte.d.ts.map +1 -1
- package/dist/views/week/WeekView.svelte +15 -15
- package/dist/views/year/YearView.svelte +12 -12
- package/package.json +9 -8
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
|
|
121
121
|
<div
|
|
122
122
|
bind:this={rowEl}
|
|
123
|
-
class="
|
|
123
|
+
class="bm-cal__week-row"
|
|
124
124
|
style="--lane-count: {lanes};"
|
|
125
125
|
role="row"
|
|
126
126
|
tabindex="-1"
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
ondragleave={handleDragLeave}
|
|
129
129
|
ondrop={handleDrop}
|
|
130
130
|
>
|
|
131
|
-
<div class="
|
|
131
|
+
<div class="bm-cal__week-number">{weekNumber}</div>
|
|
132
132
|
|
|
133
133
|
{#each weekDates as date, colIdx (colIdx)}
|
|
134
134
|
{@const isToday = isSameDay(date, today)}
|
|
@@ -144,8 +144,8 @@
|
|
|
144
144
|
{@const overflow = timedEvents.length - maxVisible}
|
|
145
145
|
|
|
146
146
|
<div
|
|
147
|
-
class="
|
|
148
|
-
class:outside
|
|
147
|
+
class="bm-cal__day"
|
|
148
|
+
class:bm-cal__day--outside={!inMonth}
|
|
149
149
|
style="grid-column: {colIdx + 2}; grid-row: 1 / -1; --lane-count: {cellLanes};"
|
|
150
150
|
role="gridcell"
|
|
151
151
|
tabindex="0"
|
|
@@ -154,14 +154,14 @@
|
|
|
154
154
|
onclick={(e) => handleDayCellClick(e, date)}
|
|
155
155
|
ondblclick={(e) => handleDayCellDoubleClick(e, date)}
|
|
156
156
|
>
|
|
157
|
-
<div class="
|
|
158
|
-
<span class="
|
|
157
|
+
<div class="bm-cal__day-number-container">
|
|
158
|
+
<span class="bm-cal__day-number" class:bm-cal__today={isToday}>
|
|
159
159
|
{formatDayLabel(date, config.locale.code)}
|
|
160
160
|
</span>
|
|
161
161
|
</div>
|
|
162
162
|
|
|
163
163
|
{#if timedEvents.length > 0}
|
|
164
|
-
<div class="
|
|
164
|
+
<div class="bm-cal__day-timed">
|
|
165
165
|
{#each showEvents as ev (ev.id)}
|
|
166
166
|
<TimedEntry
|
|
167
167
|
{ev}
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
{/each}
|
|
174
174
|
{#if !isExpanded && hasOverflow}
|
|
175
175
|
<div
|
|
176
|
-
class="
|
|
176
|
+
class="bm-cal__timed-overflow"
|
|
177
177
|
role="button"
|
|
178
178
|
tabindex="0"
|
|
179
179
|
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') ctx.onExpandMonthCell(dayMs); }}
|
|
@@ -186,12 +186,12 @@
|
|
|
186
186
|
|
|
187
187
|
{#if isExpanded && hasOverflow}
|
|
188
188
|
<div
|
|
189
|
-
class="
|
|
189
|
+
class="bm-cal__day-expand-overlay"
|
|
190
190
|
role="tooltip"
|
|
191
191
|
onmouseleave={() => ctx.onCollapseMonthCell()}
|
|
192
192
|
>
|
|
193
|
-
<div class="
|
|
194
|
-
<span class="
|
|
193
|
+
<div class="bm-cal__day-number-container">
|
|
194
|
+
<span class="bm-cal__day-number" class:bm-cal__today={isToday}>{dayNum}</span>
|
|
195
195
|
</div>
|
|
196
196
|
{#each timedEvents as ev (ev.id)}
|
|
197
197
|
<TimedEntry
|
|
@@ -209,8 +209,8 @@
|
|
|
209
209
|
{/each}
|
|
210
210
|
|
|
211
211
|
<!-- Events overlay -->
|
|
212
|
-
<div class="
|
|
213
|
-
<div class="
|
|
212
|
+
<div class="bm-cal__events-overlay">
|
|
213
|
+
<div class="bm-cal__events-grid">
|
|
214
214
|
{#each items as layoutItem, idx (`${layoutItem.segment.event.id}-${idx}`)}
|
|
215
215
|
{@const isDragged = ctx.previewEvent?.id === layoutItem.segment.event.id}
|
|
216
216
|
<EventBar
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
|
|
121
121
|
function handleColumnClick(e: MouseEvent) {
|
|
122
122
|
if (!click.accept(config.clickThresholdMs)) return;
|
|
123
|
-
if ((e.target as HTMLElement).closest('.time-event')) return;
|
|
123
|
+
if ((e.target as HTMLElement).closest('.bm-cal-time-event')) return;
|
|
124
124
|
// Single click deselects; create-dialog moves to dblclick.
|
|
125
125
|
if (ctx.selectedEventId !== null) ctx.onClearSelection();
|
|
126
126
|
}
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
function handleColumnDoubleClick(e: MouseEvent, resourceId: string) {
|
|
129
129
|
if (!click.accept(config.clickThresholdMs)) return;
|
|
130
130
|
if (!gridInnerEl) return;
|
|
131
|
-
if ((e.target as HTMLElement).closest('.time-event')) return;
|
|
131
|
+
if ((e.target as HTMLElement).closest('.bm-cal-time-event')) return;
|
|
132
132
|
const time = getTimeFromMouseY(e.clientY, gridInnerEl);
|
|
133
133
|
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
134
134
|
onResourceCellClick(currentDate, time, resourceId, rect);
|
|
@@ -136,28 +136,28 @@
|
|
|
136
136
|
</script>
|
|
137
137
|
|
|
138
138
|
{#if visibleResources.length === 0}
|
|
139
|
-
<div class="resource-
|
|
139
|
+
<div class="bm-cal-resource bm-cal-resource--empty">{config.locale.unassigned}</div>
|
|
140
140
|
{:else}
|
|
141
|
-
<div class="resource
|
|
142
|
-
<div class="
|
|
143
|
-
<div class="
|
|
144
|
-
<div class="
|
|
145
|
-
<div class="
|
|
141
|
+
<div class="bm-cal-resource">
|
|
142
|
+
<div class="bm-cal-resource__header">
|
|
143
|
+
<div class="bm-cal-resource__day-name">{dayName}</div>
|
|
144
|
+
<div class="bm-cal-resource__resources">
|
|
145
|
+
<div class="bm-cal-resource__time-spacer" style:width={`${DEFAULT_TIME_LABEL_WIDTH_DAY}px`}></div>
|
|
146
146
|
{#each visibleResources as r (r.id)}
|
|
147
|
-
<div class="
|
|
147
|
+
<div class="bm-cal-resource__resource-header" style="flex: 1 1 0; min-width: 0;">
|
|
148
148
|
{#if r.color}
|
|
149
|
-
<span class="
|
|
149
|
+
<span class="bm-cal-resource__resource-dot" style:background-color={r.color}></span>
|
|
150
150
|
{/if}
|
|
151
|
-
<span class="
|
|
151
|
+
<span class="bm-cal-resource__resource-name">{r.name}</span>
|
|
152
152
|
</div>
|
|
153
153
|
{/each}
|
|
154
154
|
</div>
|
|
155
155
|
</div>
|
|
156
156
|
|
|
157
|
-
<div class="
|
|
157
|
+
<div class="bm-cal-resource__time-grid" bind:this={timeGridEl}>
|
|
158
158
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
159
159
|
<div
|
|
160
|
-
class="
|
|
160
|
+
class="bm-cal-resource__time-grid-inner"
|
|
161
161
|
bind:this={gridInnerEl}
|
|
162
162
|
style:height={`${24 * DEFAULT_HOUR_HEIGHT}px`}
|
|
163
163
|
ondragover={handleGridDragOver}
|
|
@@ -168,11 +168,11 @@
|
|
|
168
168
|
{@const wh = config.core.workingHours}
|
|
169
169
|
{@const isOff = wh ? (hr < wh.start || hr >= wh.end) : false}
|
|
170
170
|
<div
|
|
171
|
-
class="
|
|
171
|
+
class="bm-cal-resource__hour-row{isOff ? ' bm-cal__hour-slot--off' : ''}"
|
|
172
172
|
style:top={`${hr * DEFAULT_HOUR_HEIGHT}px`}
|
|
173
173
|
style:height={`${DEFAULT_HOUR_HEIGHT}px`}
|
|
174
174
|
>
|
|
175
|
-
<div class="
|
|
175
|
+
<div class="bm-cal-resource__hour-label">
|
|
176
176
|
{hr > 0 ? `${String(hr).padStart(2, '0')}:00` : ''}
|
|
177
177
|
</div>
|
|
178
178
|
</div>
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
{#each visibleResources as r, idx (`col-${r.id}`)}
|
|
182
182
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
183
183
|
<div
|
|
184
|
-
class="
|
|
184
|
+
class="bm-cal-resource__resource-col"
|
|
185
185
|
role="gridcell"
|
|
186
186
|
tabindex="-1"
|
|
187
187
|
style:left={`calc(${DEFAULT_TIME_LABEL_WIDTH_DAY}px + ${idx} * ${colWidth})`}
|
|
@@ -214,11 +214,11 @@
|
|
|
214
214
|
|
|
215
215
|
{#if isToday}
|
|
216
216
|
<div
|
|
217
|
-
class="
|
|
217
|
+
class="bm-cal-resource__now-line"
|
|
218
218
|
style:top={`${nowHours * DEFAULT_HOUR_HEIGHT}px`}
|
|
219
219
|
style:left={`${DEFAULT_TIME_LABEL_WIDTH_DAY}px`}
|
|
220
220
|
>
|
|
221
|
-
<div class="
|
|
221
|
+
<div class="bm-cal-resource__now-dot"></div>
|
|
222
222
|
</div>
|
|
223
223
|
{/if}
|
|
224
224
|
</div>
|
|
@@ -113,35 +113,35 @@
|
|
|
113
113
|
</script>
|
|
114
114
|
|
|
115
115
|
{#if visibleResources.length === 0}
|
|
116
|
-
<div class="timeline-
|
|
117
|
-
{config.locale.unassigned
|
|
116
|
+
<div class="bm-cal-timeline bm-cal-timeline--empty">
|
|
117
|
+
{config.locale.unassigned}
|
|
118
118
|
</div>
|
|
119
119
|
{:else}
|
|
120
|
-
<div class="timeline
|
|
121
|
-
<div class="
|
|
122
|
-
<div class="
|
|
120
|
+
<div class="bm-cal-timeline">
|
|
121
|
+
<div class="bm-cal-timeline__header" style:grid-template-columns={colTemplate}>
|
|
122
|
+
<div class="bm-cal-timeline__corner"></div>
|
|
123
123
|
{#each dates as d (d.epochMs)}
|
|
124
124
|
{@const isToday = isSameDay(d, today)}
|
|
125
|
-
<div class="
|
|
125
|
+
<div class="bm-cal-timeline__date-header{isToday ? ' bm-cal-timeline__date-header--today' : ''}">
|
|
126
126
|
{dateFmt.format(new Date(d.epochMs))}
|
|
127
127
|
</div>
|
|
128
128
|
{/each}
|
|
129
129
|
</div>
|
|
130
130
|
|
|
131
|
-
<div class="
|
|
131
|
+
<div class="bm-cal-timeline__body">
|
|
132
132
|
{#each visibleResources as r (r.id)}
|
|
133
133
|
{@const items = lanesByResource.get(r.id) ?? []}
|
|
134
134
|
{@const lanes = Math.max(1, maxLanes(items))}
|
|
135
|
-
<div class="
|
|
136
|
-
<div class="
|
|
135
|
+
<div class="bm-cal-timeline__lane">
|
|
136
|
+
<div class="bm-cal-timeline__resource-label" style:width={`${DEFAULT_RESOURCE_LABEL_WIDTH}px`}>
|
|
137
137
|
{#if r.color}
|
|
138
|
-
<span class="
|
|
138
|
+
<span class="bm-cal-timeline__resource-dot" style:background-color={r.color}></span>
|
|
139
139
|
{/if}
|
|
140
|
-
<span class="
|
|
140
|
+
<span class="bm-cal-timeline__resource-name">{r.name}</span>
|
|
141
141
|
</div>
|
|
142
142
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
143
143
|
<div
|
|
144
|
-
class="
|
|
144
|
+
class="bm-cal-timeline__lane-content"
|
|
145
145
|
style:display="grid"
|
|
146
146
|
style:grid-template-columns={`repeat(${days}, 1fr)`}
|
|
147
147
|
style:grid-auto-rows="32px"
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
{@const isToday = isSameDay(d, today)}
|
|
155
155
|
<button
|
|
156
156
|
type="button"
|
|
157
|
-
class="
|
|
157
|
+
class="bm-cal-timeline__cell{isToday ? ' bm-cal-timeline__cell--today' : ''}"
|
|
158
158
|
style:grid-column={i + 1}
|
|
159
159
|
style:grid-row="1 / -1"
|
|
160
160
|
aria-label="{r.name}, {dateFmt.format(new Date(d.epochMs))}"
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
{#if items.length > 0}
|
|
54
54
|
<div
|
|
55
55
|
bind:this={rowEl}
|
|
56
|
-
class="
|
|
56
|
+
class="bm-cal-week__allday"
|
|
57
57
|
role="application"
|
|
58
58
|
ondragover={handleDragOver}
|
|
59
59
|
ondrop={handleDrop}
|
|
60
60
|
ondragleave={handleDragLeave}
|
|
61
61
|
>
|
|
62
|
-
<div class="
|
|
63
|
-
<div class="
|
|
62
|
+
<div class="bm-cal-week__allday-label">{config.locale.allDayLabel}</div>
|
|
63
|
+
<div class="bm-cal-week__allday-grid" style="--lane-count: {lanes};">
|
|
64
64
|
{#each items as layoutItem, idx (`${layoutItem.segment.event.id}-${idx}`)}
|
|
65
65
|
{@const isDragged = ctx.previewEvent?.id === layoutItem.segment.event.id}
|
|
66
66
|
<EventBar
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { getCalendarContext, getCalendarConfig, toTimeStr, buildDragInfo, getEventSlots } from '../../binding/index.js';
|
|
5
5
|
import type { DragInfo } from '../../binding/index.js';
|
|
6
6
|
import { createClickIntent, writeCalendarDragData, installTransparentDragImage } from '@bimetal/calendar-headless';
|
|
7
|
+
import { probeRender } from '@bimetal/svelte';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Layout-Position eines Termins (Pilot-Direktive 2026-06-21). Zwei
|
|
@@ -132,10 +133,22 @@
|
|
|
132
133
|
? Object.entries(slots.style).map(([k, v]) => `${k.replace(/[A-Z]/g, m => '-' + m.toLowerCase())}: ${v}`).join('; ')
|
|
133
134
|
: '');
|
|
134
135
|
const style = $derived(slotStyleStr ? `${baseStyle} ${slotStyleStr}` : baseStyle);
|
|
136
|
+
|
|
137
|
+
// The week timed-layout rebuilds its `item`/`event` wrappers every snapshot, so the raw `event`
|
|
138
|
+
// prop ref churns even for unchanged events. Route the id through an equality-gated `$derived` so
|
|
139
|
+
// the probe below tracks the STABLE id string, not the churning prop ref (the DOM-driving
|
|
140
|
+
// deriveds `style`/`renderedTitle`/… already gate the same churn to their stable values).
|
|
141
|
+
const eventId = $derived(event.id);
|
|
142
|
+
|
|
143
|
+
// v0.30 Slice 3 perf probe: re-runs (post-DOM) ONLY when this event's DOM-driving deriveds
|
|
144
|
+
// change. `style` folds in all `layout` geometry (top/height/left/width fractions), and
|
|
145
|
+
// `isSelected` is equality-gated — so a selection or geometry change elsewhere does NOT
|
|
146
|
+
// re-run unchanged events, proving fine-grained reactivity even with the context selection read.
|
|
147
|
+
$effect(() => { void style; void isSelected; void renderedTitle; void timeLabel; void duration; probeRender(eventId); });
|
|
135
148
|
</script>
|
|
136
149
|
|
|
137
150
|
<div
|
|
138
|
-
class="time-event{ghost ? ' time-event--ghost' : ''}{isSelected ? ' time-event--selected' : ''}{extraClass}"
|
|
151
|
+
class="bm-cal-time-event{ghost ? ' bm-cal-time-event--ghost' : ''}{isSelected ? ' bm-cal-time-event--selected' : ''}{extraClass}"
|
|
139
152
|
{style}
|
|
140
153
|
draggable={!ghost}
|
|
141
154
|
role="button"
|
|
@@ -155,9 +168,8 @@
|
|
|
155
168
|
{#if isFirstDay && !ghost}
|
|
156
169
|
<!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_no_noninteractive_tabindex a11y_no_static_element_interactions -->
|
|
157
170
|
<div
|
|
158
|
-
class="time-event__resize time-event__resize--top"
|
|
171
|
+
class="bm-cal-time-event__resize bm-cal-time-event__resize--top"
|
|
159
172
|
role="separator"
|
|
160
|
-
aria-label="Resize start"
|
|
161
173
|
draggable={true}
|
|
162
174
|
ondragstart={(e) => handleResizeDragStart(e, 'start')}
|
|
163
175
|
ondragend={ctx.onDragEnd}
|
|
@@ -168,9 +180,9 @@
|
|
|
168
180
|
{#if slots.content}
|
|
169
181
|
{#if typeof slots.content === 'string'}{slots.content}{:else}{@render slots.content()}{/if}
|
|
170
182
|
{:else}
|
|
171
|
-
<div class="time-event__title">{renderedTitle}</div>
|
|
183
|
+
<div class="bm-cal-time-event__title">{renderedTitle}</div>
|
|
172
184
|
{#if duration >= 0.75 && timeLabel}
|
|
173
|
-
<div class="time-event__time">{timeLabel}</div>
|
|
185
|
+
<div class="bm-cal-time-event__time">{timeLabel}</div>
|
|
174
186
|
{/if}
|
|
175
187
|
{/if}
|
|
176
188
|
{#if slots.badges}
|
|
@@ -180,9 +192,8 @@
|
|
|
180
192
|
{#if isLastDay && !ghost}
|
|
181
193
|
<!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_no_noninteractive_tabindex a11y_no_static_element_interactions -->
|
|
182
194
|
<div
|
|
183
|
-
class="time-event__resize time-event__resize--bottom"
|
|
195
|
+
class="bm-cal-time-event__resize bm-cal-time-event__resize--bottom"
|
|
184
196
|
role="separator"
|
|
185
|
-
aria-label="Resize end"
|
|
186
197
|
draggable={true}
|
|
187
198
|
ondragstart={(e) => handleResizeDragStart(e, 'end')}
|
|
188
199
|
ondragend={ctx.onDragEnd}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeEvent.svelte.d.ts","sourceRoot":"","sources":["../../../src/views/week/TimeEvent.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"TimeEvent.svelte.d.ts","sourceRoot":"","sources":["../../../src/views/week/TimeEvent.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAQ5E;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AACF,KAAK,gBAAgB,GAAI;IACtB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AA6JJ,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -120,14 +120,14 @@
|
|
|
120
120
|
|
|
121
121
|
function handleGridClick(e: MouseEvent) {
|
|
122
122
|
if (!click.accept(config.clickThresholdMs)) return;
|
|
123
|
-
if ((e.target as HTMLElement).closest('.time-event')) return;
|
|
123
|
+
if ((e.target as HTMLElement).closest('.bm-cal-time-event')) return;
|
|
124
124
|
// Single click on empty grid deselects; create-dialog moves to dblclick.
|
|
125
125
|
if (ctx.selectedEventId !== null) ctx.onClearSelection();
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
function handleGridDoubleClick(e: MouseEvent) {
|
|
129
129
|
if (!click.accept(config.clickThresholdMs)) return;
|
|
130
|
-
if ((e.target as HTMLElement).closest('.time-event')) return;
|
|
130
|
+
if ((e.target as HTMLElement).closest('.bm-cal-time-event')) return;
|
|
131
131
|
if (!gridInnerEl) return;
|
|
132
132
|
const gridRect = gridInnerEl.getBoundingClientRect();
|
|
133
133
|
const hit = timeGridHit({ x: e.clientX, y: e.clientY }, gridRect, { labelWidth: DEFAULT_TIME_LABEL_WIDTH_WEEK, hourHeight: DEFAULT_HOUR_HEIGHT, snapMinutes: timeSnapMinutes });
|
|
@@ -139,15 +139,15 @@
|
|
|
139
139
|
}
|
|
140
140
|
</script>
|
|
141
141
|
|
|
142
|
-
<div class="week
|
|
142
|
+
<div class="bm-cal-week">
|
|
143
143
|
<!-- Header -->
|
|
144
|
-
<div class="
|
|
145
|
-
<div class="
|
|
144
|
+
<div class="bm-cal-week__header">
|
|
145
|
+
<div class="bm-cal-week__corner">{config.locale.calendarWeek} {weekNumber}</div>
|
|
146
146
|
{#each weekDates as date, i (i)}
|
|
147
147
|
{@const isToday = isSameDay(date, currentNow)}
|
|
148
|
-
<div class="
|
|
149
|
-
<span class="
|
|
150
|
-
<span class="
|
|
148
|
+
<div class="bm-cal-week__day-header{isToday ? ' bm-cal-week__day-header--today' : ''}">
|
|
149
|
+
<span class="bm-cal-week__day-name">{config.locale.dayNamesShort[i]}</span>
|
|
150
|
+
<span class="bm-cal-week__day-number{isToday ? ' bm-cal-week__day-number--today' : ''}">
|
|
151
151
|
{getDayOfMonth(date)}
|
|
152
152
|
</span>
|
|
153
153
|
</div>
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
<!-- Time grid -->
|
|
161
161
|
<div
|
|
162
162
|
bind:this={timeGridEl}
|
|
163
|
-
class="
|
|
163
|
+
class="bm-cal-week__time-grid"
|
|
164
164
|
role="grid"
|
|
165
165
|
tabindex="0"
|
|
166
166
|
ondragover={handleGridDragOver}
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
>
|
|
174
174
|
<div
|
|
175
175
|
bind:this={gridInnerEl}
|
|
176
|
-
class="
|
|
176
|
+
class="bm-cal-week__time-grid-inner"
|
|
177
177
|
style="height: {24 * DEFAULT_HOUR_HEIGHT}px;"
|
|
178
178
|
>
|
|
179
179
|
<!-- Hour rows -->
|
|
@@ -181,10 +181,10 @@
|
|
|
181
181
|
{@const wh = config.core.workingHours}
|
|
182
182
|
{@const isOff = wh ? (hr < wh.start || hr >= wh.end) : false}
|
|
183
183
|
<div
|
|
184
|
-
class="
|
|
184
|
+
class="bm-cal-week__hour-row{isOff ? ' bm-cal__hour-slot--off' : ''}"
|
|
185
185
|
style="top: {hr * DEFAULT_HOUR_HEIGHT}px; height: {DEFAULT_HOUR_HEIGHT}px;"
|
|
186
186
|
>
|
|
187
|
-
<div class="
|
|
187
|
+
<div class="bm-cal-week__hour-label">
|
|
188
188
|
{hr > 0 ? `${String(hr).padStart(2, '0')}:00` : ''}
|
|
189
189
|
</div>
|
|
190
190
|
</div>
|
|
@@ -193,7 +193,7 @@
|
|
|
193
193
|
<!-- Day columns -->
|
|
194
194
|
{#each weekDates as _, col (col)}
|
|
195
195
|
<div
|
|
196
|
-
class="
|
|
196
|
+
class="bm-cal-week__day-col"
|
|
197
197
|
style="left: calc({DEFAULT_TIME_LABEL_WIDTH_WEEK}px + {col} * (100% - {DEFAULT_TIME_LABEL_WIDTH_WEEK}px) / 7); width: calc((100% - {DEFAULT_TIME_LABEL_WIDTH_WEEK}px) / 7);"
|
|
198
198
|
></div>
|
|
199
199
|
{/each}
|
|
@@ -221,10 +221,10 @@
|
|
|
221
221
|
<!-- Now line -->
|
|
222
222
|
{#if nowCol >= 0}
|
|
223
223
|
<div
|
|
224
|
-
class="
|
|
224
|
+
class="bm-cal-week__now-line"
|
|
225
225
|
style="top: {nowHours * DEFAULT_HOUR_HEIGHT}px; left: calc({DEFAULT_TIME_LABEL_WIDTH_WEEK}px + {nowCol} * (100% - {DEFAULT_TIME_LABEL_WIDTH_WEEK}px) / 7); width: calc((100% - {DEFAULT_TIME_LABEL_WIDTH_WEEK}px) / 7);"
|
|
226
226
|
>
|
|
227
|
-
<div class="
|
|
227
|
+
<div class="bm-cal-week__now-dot"></div>
|
|
228
228
|
</div>
|
|
229
229
|
{/if}
|
|
230
230
|
</div>
|
|
@@ -51,22 +51,22 @@
|
|
|
51
51
|
}
|
|
52
52
|
</script>
|
|
53
53
|
|
|
54
|
-
<div class="year
|
|
54
|
+
<div class="bm-cal-year">
|
|
55
55
|
{#each months as { month, label, weeks } (month)}
|
|
56
|
-
<div class="year-month">
|
|
56
|
+
<div class="bm-cal-year-month">
|
|
57
57
|
{#if onMonthClick}
|
|
58
|
-
<button type="button" class="year-month__header" onclick={() => onMonthClick?.(year, month)}>
|
|
58
|
+
<button type="button" class="bm-cal-year-month__header" onclick={() => onMonthClick?.(year, month)}>
|
|
59
59
|
{label}
|
|
60
60
|
</button>
|
|
61
61
|
{:else}
|
|
62
|
-
<div class="year-month__header">{label}</div>
|
|
62
|
+
<div class="bm-cal-year-month__header">{label}</div>
|
|
63
63
|
{/if}
|
|
64
|
-
<div class="year-month__day-headers">
|
|
64
|
+
<div class="bm-cal-year-month__day-headers">
|
|
65
65
|
{#each config.locale.dayNamesShort as n (n)}
|
|
66
|
-
<div class="year-month__day-header">{n[0]}</div>
|
|
66
|
+
<div class="bm-cal-year-month__day-header">{n[0]}</div>
|
|
67
67
|
{/each}
|
|
68
68
|
</div>
|
|
69
|
-
<div class="year-month__days">
|
|
69
|
+
<div class="bm-cal-year-month__days">
|
|
70
70
|
{#each weeks as week, wIdx (wIdx)}
|
|
71
71
|
{#each week as date (date.epochMs)}
|
|
72
72
|
{@const inMonth = getMonth(date) === month}
|
|
@@ -75,14 +75,14 @@
|
|
|
75
75
|
<button
|
|
76
76
|
type="button"
|
|
77
77
|
class={
|
|
78
|
-
'year-month__day'
|
|
79
|
-
+ (inMonth ? '' : ' year-month__day--outside')
|
|
80
|
-
+ (isToday ? ' year-month__day--today' : '')
|
|
81
|
-
+ (hasEvents ? ' year-month__day--has-events' : '')
|
|
78
|
+
'bm-cal-year-month__day'
|
|
79
|
+
+ (inMonth ? '' : ' bm-cal-year-month__day--outside')
|
|
80
|
+
+ (isToday ? ' bm-cal-year-month__day--today' : '')
|
|
81
|
+
+ (hasEvents ? ' bm-cal-year-month__day--has-events' : '')
|
|
82
82
|
}
|
|
83
83
|
onclick={(e) => dayClick(e, date)}
|
|
84
84
|
>
|
|
85
|
-
<span class="year-month__day-num">{getDayOfMonth(date)}</span>
|
|
85
|
+
<span class="bm-cal-year-month__day-num">{getDayOfMonth(date)}</span>
|
|
86
86
|
</button>
|
|
87
87
|
{/each}
|
|
88
88
|
{/each}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bimetal/calendar-svelte-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Default Svelte 5 calendar UI components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -27,13 +27,14 @@
|
|
|
27
27
|
"prepublishOnly": "npm run build"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@bimetal/svelte": "^0.
|
|
31
|
-
"@bimetal/core": "^0.
|
|
32
|
-
"@bimetal/calendar-core": "^0.
|
|
33
|
-
"@bimetal/calendar-data": "^0.
|
|
34
|
-
"@bimetal/calendar-headless": "^0.
|
|
35
|
-
"@bimetal/
|
|
36
|
-
"@bimetal/calendar-
|
|
30
|
+
"@bimetal/svelte": "^0.32.0",
|
|
31
|
+
"@bimetal/core": "^0.32.0",
|
|
32
|
+
"@bimetal/calendar-core": "^0.32.0",
|
|
33
|
+
"@bimetal/calendar-data": "^0.32.0",
|
|
34
|
+
"@bimetal/calendar-headless": "^0.32.0",
|
|
35
|
+
"@bimetal/a11y-dom": "^0.32.0",
|
|
36
|
+
"@bimetal/calendar-rules": "^0.32.0",
|
|
37
|
+
"@bimetal/calendar-themes": "^0.32.0"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
39
40
|
"svelte": "^5.46.4"
|