@bimetal/calendar-svelte-components 0.30.0 → 0.34.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.
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { DomainEvent } from '@bimetal/calendar-data';
3
+ import { formatHistoryTimestamp } from '@bimetal/calendar-core';
3
4
  import { getCalendarConfig } from '../binding/index.js';
4
5
 
5
6
  const eventTypeColors: Record<string, string> = {
@@ -22,12 +23,7 @@
22
23
  const config = getCalendarConfig();
23
24
  const eventTypeLabels = config.locale.historyEventTypes;
24
25
 
25
- function formatTime(timestamp: number): string {
26
- return new Date(timestamp).toLocaleString(config.locale.code, {
27
- day: '2-digit', month: '2-digit', year: 'numeric',
28
- hour: '2-digit', minute: '2-digit',
29
- });
30
- }
26
+ const formatTime = (timestamp: number): string => formatHistoryTimestamp(timestamp, config.locale.code, config.core.timezone);
31
27
 
32
28
  function getSummary(event: DomainEvent): string {
33
29
  const payload = event.payload as Record<string, unknown>;
@@ -47,40 +43,40 @@
47
43
  }
48
44
  </script>
49
45
 
50
- <div class="event-history">
51
- <div class="event-history__header">
52
- <button class="event-history__back" onclick={onBack}>&larr;</button>
53
- <span class="event-history__title">{config.locale.historyTitle}</span>
46
+ <div class="bm-cal-event-history">
47
+ <div class="bm-cal-event-history__header">
48
+ <button class="bm-cal-event-history__back" onclick={onBack}>&larr;</button>
49
+ <span class="bm-cal-event-history__title">{config.locale.historyTitle}</span>
54
50
  </div>
55
51
 
56
52
  {#if history.length === 0}
57
- <div class="event-history__loading">{config.locale.historyLoading}</div>
53
+ <div class="bm-cal-event-history__loading">{config.locale.historyLoading}</div>
58
54
  {/if}
59
55
 
60
- <div class="event-history__timeline">
56
+ <div class="bm-cal-event-history__timeline">
61
57
  {#each history as entry, idx (entry.envelope.id ?? idx)}
62
- <div class="event-history__entry">
63
- <div class="event-history__dot-col">
58
+ <div class="bm-cal-event-history__entry">
59
+ <div class="bm-cal-event-history__dot-col">
64
60
  <div
65
- class="event-history__dot"
61
+ class="bm-cal-event-history__dot"
66
62
  style:background-color={eventTypeColors[entry.type] ?? '#8E8E93'}
67
63
  ></div>
68
64
  {#if idx < history.length - 1}
69
- <div class="event-history__line"></div>
65
+ <div class="bm-cal-event-history__line"></div>
70
66
  {/if}
71
67
  </div>
72
- <div class="event-history__content">
73
- <div class="event-history__entry-header">
68
+ <div class="bm-cal-event-history__content">
69
+ <div class="bm-cal-event-history__entry-header">
74
70
  <span
75
- class="event-history__badge"
71
+ class="bm-cal-event-history__badge"
76
72
  style:background-color={eventTypeColors[entry.type] ?? '#8E8E93'}
77
73
  >
78
74
  {eventTypeLabels[entry.type] ?? entry.type}
79
75
  </span>
80
- <span class="event-history__time">{formatTime(entry.envelope.timestamp)}</span>
76
+ <span class="bm-cal-event-history__time">{formatTime(entry.envelope.timestamp)}</span>
81
77
  </div>
82
78
  {#if getSummary(entry)}
83
- <div class="event-history__summary">{getSummary(entry)}</div>
79
+ <div class="bm-cal-event-history__summary">{getSummary(entry)}</div>
84
80
  {/if}
85
81
  </div>
86
82
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"EventHistory.svelte.d.ts","sourceRoot":"","sources":["../../src/components/EventHistory.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGzD,KAAK,gBAAgB,GAAI;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAmFJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"EventHistory.svelte.d.ts","sourceRoot":"","sources":["../../src/components/EventHistory.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAIzD,KAAK,gBAAgB,GAAI;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AA+EJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -13,11 +13,11 @@
13
13
  </script>
14
14
 
15
15
  {#if resources.length > 0}
16
- <div class="resource-filter">
16
+ <div class="bm-cal-resource-filter">
17
17
  {#each resources as r (r.id)}
18
18
  <button
19
19
  type="button"
20
- class="resource-filter__pill{hiddenResources.has(r.id) ? ' resource-filter__pill--hidden' : ''}"
20
+ class="bm-cal-resource-filter__pill{hiddenResources.has(r.id) ? ' bm-cal-resource-filter__pill--hidden' : ''}"
21
21
  style:border-left-color={r.color ?? 'transparent'}
22
22
  onclick={() => onToggle(r.id)}
23
23
  >
@@ -37,11 +37,11 @@
37
37
  </script>
38
38
 
39
39
  {#if ctx.lastAction}
40
- <div class="undo-toast" role="status">
41
- <span class="undo-toast__text">{ctx.lastAction.description}</span>
42
- <button class="undo-toast__btn" onclick={handleUndo}>
43
- {config.locale.undo ?? 'Undo'}
40
+ <div class="bm-cal__toast" role="status">
41
+ <span class="bm-cal__toast-text">{ctx.lastAction.description}</span>
42
+ <button class="bm-cal__toast-btn" onclick={handleUndo}>
43
+ {config.locale.undo}
44
44
  </button>
45
- <button class="undo-toast__dismiss" onclick={() => ctx.dismissUndo()}>&times;</button>
45
+ <button class="bm-cal__toast-dismiss" onclick={() => ctx.dismissUndo()}>&times;</button>
46
46
  </div>
47
47
  {/if}
@@ -32,7 +32,7 @@
32
32
 
33
33
  <!-- svelte-ignore a11y_click_events_have_key_events -->
34
34
  <div
35
- class="agenda-view__row agenda-view__event{isSelected ? ' agenda-view__event--selected' : ''}{extraClass}"
35
+ class="bm-cal-agenda__row bm-cal-agenda__event{isSelected ? ' bm-cal-agenda__event--selected' : ''}{extraClass}"
36
36
  style={slotStyleStr}
37
37
  role="button"
38
38
  tabindex="0"
@@ -43,12 +43,12 @@
43
43
  {#if slots.content}
44
44
  {#if typeof slots.content === 'string'}{slots.content}{:else}{@render slots.content()}{/if}
45
45
  {:else}
46
- <div class="agenda-view__event-color" style:background-color={event.metadata.color ?? '#007AFF'}></div>
47
- <div class="agenda-view__event-content">
48
- <div class="agenda-view__event-title">{renderedTitle}</div>
49
- <div class="agenda-view__event-time">{timeLabel}</div>
46
+ <div class="bm-cal-agenda__event-color" style:background-color={event.metadata.color ?? '#007AFF'}></div>
47
+ <div class="bm-cal-agenda__event-content">
48
+ <div class="bm-cal-agenda__event-title">{renderedTitle}</div>
49
+ <div class="bm-cal-agenda__event-time">{timeLabel}</div>
50
50
  </div>
51
- <div class="agenda-view__event-calendar">{category}</div>
51
+ <div class="bm-cal-agenda__event-calendar">{category}</div>
52
52
  {/if}
53
53
  {#if slots.badges}
54
54
  {#if typeof slots.badges === 'string'}{slots.badges}{:else}{@render slots.badges()}{/if}
@@ -61,20 +61,20 @@
61
61
  }
62
62
  </script>
63
63
 
64
- <div class="agenda-view" bind:this={scrollEl}>
64
+ <div class="bm-cal-agenda" bind:this={scrollEl}>
65
65
  {#if agenda.empty}
66
- <div class="agenda-view__empty">{config.locale.noEvents}</div>
66
+ <div class="bm-cal-agenda__empty">{config.locale.noEvents}</div>
67
67
  {:else}
68
68
  {#if agenda.offsetTop > 0}
69
- <div class="agenda-view__spacer" style:height={`${agenda.offsetTop}px`} aria-hidden="true"></div>
69
+ <div class="bm-cal-agenda__spacer" style:height={`${agenda.offsetTop}px`} aria-hidden="true"></div>
70
70
  {/if}
71
71
  {#each agenda.rows as row (row.key)}
72
72
  {#if row.kind === 'header'}
73
- <div class="agenda-view__row agenda-view__row--header{row.isToday ? ' agenda-view__row--today' : ''}">
74
- <span class="agenda-view__date-number">{row.dayOfMonth}</span>
75
- <div class="agenda-view__date-text">
76
- <span class="agenda-view__date-weekday">{row.weekday}</span>
77
- <span class="agenda-view__date-full">{row.dateFull}</span>
73
+ <div class="bm-cal-agenda__row bm-cal-agenda__row--header{row.isToday ? ' bm-cal-agenda__row--today' : ''}">
74
+ <span class="bm-cal-agenda__date-number">{row.dayOfMonth}</span>
75
+ <div class="bm-cal-agenda__date-text">
76
+ <span class="bm-cal-agenda__date-weekday">{row.weekday}</span>
77
+ <span class="bm-cal-agenda__date-full">{row.dateFull}</span>
78
78
  </div>
79
79
  </div>
80
80
  {:else}
@@ -91,7 +91,7 @@
91
91
  {/if}
92
92
  {/each}
93
93
  {#if agenda.offsetBottom > 0}
94
- <div class="agenda-view__spacer" style:height={`${agenda.offsetBottom}px`} aria-hidden="true"></div>
94
+ <div class="bm-cal-agenda__spacer" style:height={`${agenda.offsetBottom}px`} aria-hidden="true"></div>
95
95
  {/if}
96
96
  {/if}
97
97
  </div>
@@ -29,7 +29,7 @@
29
29
 
30
30
  <!-- svelte-ignore a11y_click_events_have_key_events -->
31
31
  <div
32
- class="day-view__allday-event{isSelected ? ' day-view__allday-event--selected' : ''}{extraClass}"
32
+ class="bm-cal-day__allday-event{isSelected ? ' bm-cal-day__allday-event--selected' : ''}{extraClass}"
33
33
  style={fullStyle}
34
34
  role="button"
35
35
  tabindex="0"
@@ -118,14 +118,14 @@
118
118
 
119
119
  function handleGridClick(e: MouseEvent) {
120
120
  if (!click.accept(config.clickThresholdMs)) return;
121
- if ((e.target as HTMLElement).closest('.time-event')) return;
121
+ if ((e.target as HTMLElement).closest('.bm-cal-time-event')) return;
122
122
  // Single click on empty grid deselects; create-dialog moves to dblclick.
123
123
  if (ctx.selectedEventId !== null) ctx.onClearSelection();
124
124
  }
125
125
 
126
126
  function handleGridDoubleClick(e: MouseEvent) {
127
127
  if (!click.accept(config.clickThresholdMs)) return;
128
- if ((e.target as HTMLElement).closest('.time-event')) return;
128
+ if ((e.target as HTMLElement).closest('.bm-cal-time-event')) return;
129
129
  const time = getTimeFromMouseY(e.clientY);
130
130
  // Tag + gesnapte Zeit über den geteilten Parser (kein split, wie WeekView).
131
131
  const clickedDt = parseDateTimeStr(toDateStr(currentDate), time, currentDate.timezone);
@@ -156,20 +156,20 @@
156
156
  }
157
157
  </script>
158
158
 
159
- <div class="day-view">
159
+ <div class="bm-cal-day">
160
160
  <!-- Header -->
161
- <div class="day-view__header">
162
- <span class="day-view__day-name">{dayName}</span>
163
- <span class="day-view__day-number{isToday ? ' day-view__day-number--today' : ''}">
161
+ <div class="bm-cal-day__header">
162
+ <span class="bm-cal-day__day-name">{dayName}</span>
163
+ <span class="bm-cal-day__day-number{isToday ? ' bm-cal-day__day-number--today' : ''}">
164
164
  {getDayOfMonth(currentDate)}
165
165
  </span>
166
166
  </div>
167
167
 
168
168
  <!-- All-day events -->
169
169
  {#if allDayEvents.length > 0}
170
- <div class="day-view__allday">
171
- <div class="day-view__allday-label">{config.locale.allDayLabel}</div>
172
- <div class="day-view__allday-list">
170
+ <div class="bm-cal-day__allday">
171
+ <div class="bm-cal-day__allday-label">{config.locale.allDayLabel}</div>
172
+ <div class="bm-cal-day__allday-list">
173
173
  {#each allDayEvents as ev (ev.id)}
174
174
  <AllDayEvent
175
175
  {ev}
@@ -186,7 +186,7 @@
186
186
  <!-- Time grid -->
187
187
  <div
188
188
  bind:this={timeGridEl}
189
- class="day-view__time-grid"
189
+ class="bm-cal-day__time-grid"
190
190
  role="grid"
191
191
  tabindex="0"
192
192
  ondragover={handleGridDragOver}
@@ -199,7 +199,7 @@
199
199
  >
200
200
  <div
201
201
  bind:this={gridInnerEl}
202
- class="day-view__time-grid-inner"
202
+ class="bm-cal-day__time-grid-inner"
203
203
  style="height: {24 * DEFAULT_HOUR_HEIGHT}px;"
204
204
  >
205
205
  <!-- Hour rows -->
@@ -207,10 +207,10 @@
207
207
  {@const wh = config.core.workingHours}
208
208
  {@const isOff = wh ? (hr < wh.start || hr >= wh.end) : false}
209
209
  <div
210
- class="day-view__hour-row{isOff ? ' hour-slot--off' : ''}"
210
+ class="bm-cal-day__hour-row{isOff ? ' bm-cal__hour-slot--off' : ''}"
211
211
  style="top: {hr * DEFAULT_HOUR_HEIGHT}px; height: {DEFAULT_HOUR_HEIGHT}px;"
212
212
  >
213
- <div class="day-view__hour-label">
213
+ <div class="bm-cal-day__hour-label">
214
214
  {hr > 0 ? `${String(hr).padStart(2, '0')}:00` : ''}
215
215
  </div>
216
216
  </div>
@@ -218,7 +218,7 @@
218
218
 
219
219
  <!-- Day column -->
220
220
  <div
221
- class="day-view__day-col"
221
+ class="bm-cal-day__day-col"
222
222
  style="left: {DEFAULT_TIME_LABEL_WIDTH_DAY}px; width: calc(100% - {DEFAULT_TIME_LABEL_WIDTH_DAY}px);"
223
223
  ></div>
224
224
 
@@ -243,8 +243,8 @@
243
243
 
244
244
  <!-- Now line -->
245
245
  {#if isToday}
246
- <div class="day-view__now-line" style="top: {nowHours * DEFAULT_HOUR_HEIGHT}px;">
247
- <div class="day-view__now-dot"></div>
246
+ <div class="bm-cal-day__now-line" style="top: {nowHours * DEFAULT_HOUR_HEIGHT}px;">
247
+ <div class="bm-cal-day__now-dot"></div>
248
248
  </div>
249
249
  {/if}
250
250
  </div>
@@ -44,11 +44,11 @@
44
44
  });
45
45
  </script>
46
46
 
47
- <div class="month-grid">
48
- <div class="day-headers">
49
- <div class="header-spacer"></div>
47
+ <div class="bm-cal__month-grid">
48
+ <div class="bm-cal__day-headers">
49
+ <div class="bm-cal__header-spacer"></div>
50
50
  {#each config.locale.dayNamesShort as name (name)}
51
- <div class="day-header">{name}</div>
51
+ <div class="bm-cal__day-header">{name}</div>
52
52
  {/each}
53
53
  </div>
54
54
 
@@ -33,7 +33,7 @@
33
33
 
34
34
  <!-- svelte-ignore a11y_click_events_have_key_events -->
35
35
  <div
36
- class="timed-entry{isSelected ? ' timed-entry--selected' : ''}{extraClass}"
36
+ class="bm-cal-timed-entry{isSelected ? ' bm-cal-timed-entry--selected' : ''}{extraClass}"
37
37
  style={slotStyleStr}
38
38
  role="button"
39
39
  tabindex="0"
@@ -45,11 +45,11 @@
45
45
  {#if slots.content}
46
46
  {#if typeof slots.content === 'string'}{slots.content}{:else}{@render slots.content()}{/if}
47
47
  {:else}
48
- <span class="timed-entry__dot" style:background-color={ev.metadata.color ?? '#007AFF'}></span>
49
- <span class="timed-entry__time">
48
+ <span class="bm-cal-timed-entry__dot" style:background-color={ev.metadata.color ?? '#007AFF'}></span>
49
+ <span class="bm-cal-timed-entry__time">
50
50
  {toTimeStr(ev.timeRange.start)}
51
51
  </span>
52
- <span class="timed-entry__title">{renderedTitle}</span>
52
+ <span class="bm-cal-timed-entry__title">{renderedTitle}</span>
53
53
  {/if}
54
54
  {#if slots.badges}
55
55
  {#if typeof slots.badges === 'string'}{slots.badges}{:else}{@render slots.badges()}{/if}
@@ -120,7 +120,7 @@
120
120
 
121
121
  <div
122
122
  bind:this={rowEl}
123
- class="week-row"
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="week-number">{weekNumber}</div>
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="day-cell"
148
- class:outside-month={!inMonth}
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="day-number-container">
158
- <span class="day-number" class:today={isToday}>
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="day-cell__timed">
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="timed-overflow"
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="day-cell__expand-overlay"
189
+ class="bm-cal__day-expand-overlay"
190
190
  role="tooltip"
191
191
  onmouseleave={() => ctx.onCollapseMonthCell()}
192
192
  >
193
- <div class="day-number-container">
194
- <span class="day-number" class:today={isToday}>{dayNum}</span>
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="events-overlay">
213
- <div class="events-grid">
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-view resource-view--empty">{config.locale.unassigned ?? 'No resource selected'}</div>
139
+ <div class="bm-cal-resource bm-cal-resource--empty">{config.locale.unassigned}</div>
140
140
  {:else}
141
- <div class="resource-view">
142
- <div class="resource-view__header">
143
- <div class="resource-view__day-name">{dayName}</div>
144
- <div class="resource-view__resources">
145
- <div class="resource-view__time-spacer" style:width={`${DEFAULT_TIME_LABEL_WIDTH_DAY}px`}></div>
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="resource-view__resource-header" style="flex: 1 1 0; min-width: 0;">
147
+ <div class="bm-cal-resource__resource-header" style="flex: 1 1 0; min-width: 0;">
148
148
  {#if r.color}
149
- <span class="resource-view__resource-dot" style:background-color={r.color}></span>
149
+ <span class="bm-cal-resource__resource-dot" style:background-color={r.color}></span>
150
150
  {/if}
151
- <span class="resource-view__resource-name">{r.name}</span>
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="resource-view__time-grid" bind:this={timeGridEl}>
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="resource-view__time-grid-inner"
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="resource-view__hour-row{isOff ? ' hour-slot--off' : ''}"
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="resource-view__hour-label">
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="resource-view__resource-col"
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="resource-view__now-line"
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="resource-view__now-dot"></div>
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-view timeline-view--empty">
117
- {config.locale.unassigned ?? 'No resource selected'}
116
+ <div class="bm-cal-timeline bm-cal-timeline--empty">
117
+ {config.locale.unassigned}
118
118
  </div>
119
119
  {:else}
120
- <div class="timeline-view">
121
- <div class="timeline-view__header" style:grid-template-columns={colTemplate}>
122
- <div class="timeline-view__corner"></div>
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="timeline-view__date-header{isToday ? ' timeline-view__date-header--today' : ''}">
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="timeline-view__body">
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="timeline-view__lane">
136
- <div class="timeline-view__resource-label" style:width={`${DEFAULT_RESOURCE_LABEL_WIDTH}px`}>
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="timeline-view__resource-dot" style:background-color={r.color}></span>
138
+ <span class="bm-cal-timeline__resource-dot" style:background-color={r.color}></span>
139
139
  {/if}
140
- <span class="timeline-view__resource-name">{r.name}</span>
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="timeline-view__lane-content"
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="timeline-view__cell{isToday ? ' timeline-view__cell--today' : ''}"
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="week-view__allday"
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="week-view__allday-label">{config.locale.allDayLabel}</div>
63
- <div class="week-view__allday-grid" style="--lane-count: {lanes};">
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
@@ -148,7 +148,7 @@
148
148
  </script>
149
149
 
150
150
  <div
151
- 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}"
152
152
  {style}
153
153
  draggable={!ghost}
154
154
  role="button"
@@ -168,9 +168,8 @@
168
168
  {#if isFirstDay && !ghost}
169
169
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_no_noninteractive_tabindex a11y_no_static_element_interactions -->
170
170
  <div
171
- class="time-event__resize time-event__resize--top"
171
+ class="bm-cal-time-event__resize bm-cal-time-event__resize--top"
172
172
  role="separator"
173
- aria-label="Resize start"
174
173
  draggable={true}
175
174
  ondragstart={(e) => handleResizeDragStart(e, 'start')}
176
175
  ondragend={ctx.onDragEnd}
@@ -181,9 +180,9 @@
181
180
  {#if slots.content}
182
181
  {#if typeof slots.content === 'string'}{slots.content}{:else}{@render slots.content()}{/if}
183
182
  {:else}
184
- <div class="time-event__title">{renderedTitle}</div>
183
+ <div class="bm-cal-time-event__title">{renderedTitle}</div>
185
184
  {#if duration >= 0.75 && timeLabel}
186
- <div class="time-event__time">{timeLabel}</div>
185
+ <div class="bm-cal-time-event__time">{timeLabel}</div>
187
186
  {/if}
188
187
  {/if}
189
188
  {#if slots.badges}
@@ -193,9 +192,8 @@
193
192
  {#if isLastDay && !ghost}
194
193
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_no_noninteractive_tabindex a11y_no_static_element_interactions -->
195
194
  <div
196
- class="time-event__resize time-event__resize--bottom"
195
+ class="bm-cal-time-event__resize bm-cal-time-event__resize--bottom"
197
196
  role="separator"
198
- aria-label="Resize end"
199
197
  draggable={true}
200
198
  ondragstart={(e) => handleResizeDragStart(e, 'end')}
201
199
  ondragend={ctx.onDragEnd}