@neural-ui/core 1.4.0 → 1.5.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 +2 -1
- package/calendar/package.json +4 -0
- package/fesm2022/neural-ui-core-autocomplete.mjs +2 -2
- package/fesm2022/neural-ui-core-block-ui.mjs +2 -2
- package/fesm2022/neural-ui-core-button.mjs +2 -2
- package/fesm2022/neural-ui-core-button.mjs.map +1 -1
- package/fesm2022/neural-ui-core-calendar.mjs +551 -0
- package/fesm2022/neural-ui-core-calendar.mjs.map +1 -0
- package/fesm2022/neural-ui-core-chip.mjs +2 -2
- package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
- package/fesm2022/neural-ui-core-confirm-dialog.mjs +2 -2
- package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -1
- package/fesm2022/neural-ui-core-dashboard-grid.mjs +2 -2
- package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
- package/fesm2022/neural-ui-core-date-input.mjs +2 -2
- package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
- package/fesm2022/neural-ui-core-image-gallery.mjs +224 -0
- package/fesm2022/neural-ui-core-image-gallery.mjs.map +1 -0
- package/fesm2022/neural-ui-core-input.mjs +2 -2
- package/fesm2022/neural-ui-core-kanban.mjs +270 -0
- package/fesm2022/neural-ui-core-kanban.mjs.map +1 -0
- package/fesm2022/neural-ui-core-meter-group.mjs +2 -2
- package/fesm2022/neural-ui-core-multiselect.mjs +13 -2
- package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
- package/fesm2022/neural-ui-core-nav.mjs +2 -2
- package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
- package/fesm2022/neural-ui-core-number-input.mjs +2 -2
- package/fesm2022/neural-ui-core-pagination.mjs +2 -2
- package/fesm2022/neural-ui-core-pagination.mjs.map +1 -1
- package/fesm2022/neural-ui-core-progress-bar.mjs +2 -2
- package/fesm2022/neural-ui-core-scheduler-gantt.mjs +289 -0
- package/fesm2022/neural-ui-core-scheduler-gantt.mjs.map +1 -0
- package/fesm2022/neural-ui-core-select.mjs +31 -9
- package/fesm2022/neural-ui-core-select.mjs.map +1 -1
- package/fesm2022/neural-ui-core-slider.mjs +2 -2
- package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
- package/fesm2022/neural-ui-core-split-button.mjs +2 -2
- package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
- package/fesm2022/neural-ui-core-stepper.mjs +2 -2
- package/fesm2022/neural-ui-core-stepper.mjs.map +1 -1
- package/fesm2022/neural-ui-core-table.mjs +273 -19
- package/fesm2022/neural-ui-core-table.mjs.map +1 -1
- package/fesm2022/neural-ui-core-textarea.mjs +2 -2
- package/fesm2022/neural-ui-core-timeline-grid.mjs +215 -0
- package/fesm2022/neural-ui-core-timeline-grid.mjs.map +1 -0
- package/fesm2022/neural-ui-core-toggle-button-group.mjs +2 -2
- package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
- package/fesm2022/neural-ui-core-tree-table.mjs +262 -0
- package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -0
- package/fesm2022/neural-ui-core-tree.mjs +413 -0
- package/fesm2022/neural-ui-core-tree.mjs.map +1 -0
- package/fesm2022/neural-ui-core-uploader.mjs +624 -0
- package/fesm2022/neural-ui-core-uploader.mjs.map +1 -0
- package/fesm2022/neural-ui-core-virtual-list.mjs +2 -2
- package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
- package/fesm2022/neural-ui-core.mjs +3 -1
- package/fesm2022/neural-ui-core.mjs.map +1 -1
- package/image-gallery/package.json +4 -0
- package/kanban/package.json +4 -0
- package/package.json +34 -2
- package/scheduler-gantt/package.json +4 -0
- package/styles/_tokens.scss +13 -4
- package/timeline-grid/package.json +4 -0
- package/tree/package.json +4 -0
- package/tree-table/package.json +4 -0
- package/types/neural-ui-core-calendar.d.ts +79 -0
- package/types/neural-ui-core-image-gallery.d.ts +26 -0
- package/types/neural-ui-core-kanban.d.ts +52 -0
- package/types/neural-ui-core-multiselect.d.ts +1 -0
- package/types/neural-ui-core-scheduler-gantt.d.ts +68 -0
- package/types/neural-ui-core-select.d.ts +2 -0
- package/types/neural-ui-core-table.d.ts +44 -2
- package/types/neural-ui-core-timeline-grid.d.ts +55 -0
- package/types/neural-ui-core-tree-table.d.ts +72 -0
- package/types/neural-ui-core-tree.d.ts +52 -0
- package/types/neural-ui-core-uploader.d.ts +98 -0
- package/uploader/package.json +4 -0
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, signal, computed, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
function startOfDay(date) {
|
|
5
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
6
|
+
}
|
|
7
|
+
function sameDay(a, b) {
|
|
8
|
+
return (a.getFullYear() === b.getFullYear() &&
|
|
9
|
+
a.getMonth() === b.getMonth() &&
|
|
10
|
+
a.getDate() === b.getDate());
|
|
11
|
+
}
|
|
12
|
+
function addDays(date, amount) {
|
|
13
|
+
const next = new Date(date);
|
|
14
|
+
next.setDate(next.getDate() + amount);
|
|
15
|
+
return next;
|
|
16
|
+
}
|
|
17
|
+
function addMonths(date, amount) {
|
|
18
|
+
return new Date(date.getFullYear(), date.getMonth() + amount, date.getDate());
|
|
19
|
+
}
|
|
20
|
+
function startOfWeek(date) {
|
|
21
|
+
const normalized = startOfDay(date);
|
|
22
|
+
const day = normalized.getDay();
|
|
23
|
+
const diff = day === 0 ? -6 : 1 - day;
|
|
24
|
+
return addDays(normalized, diff);
|
|
25
|
+
}
|
|
26
|
+
const EN_CALENDAR_LABELS = {
|
|
27
|
+
previousButtonAriaLabel: 'Previous',
|
|
28
|
+
nextButtonAriaLabel: 'Next',
|
|
29
|
+
todayButton: 'Today',
|
|
30
|
+
allDay: 'All day',
|
|
31
|
+
noEvents: 'No events',
|
|
32
|
+
eventCount: (count) => `${count} ${count === 1 ? 'event' : 'events'}`,
|
|
33
|
+
moreEvents: (count) => `+${count} more`,
|
|
34
|
+
};
|
|
35
|
+
const ES_CALENDAR_LABELS = {
|
|
36
|
+
previousButtonAriaLabel: 'Anterior',
|
|
37
|
+
nextButtonAriaLabel: 'Siguiente',
|
|
38
|
+
todayButton: 'Hoy',
|
|
39
|
+
allDay: 'Todo el dia',
|
|
40
|
+
noEvents: 'Sin eventos',
|
|
41
|
+
eventCount: (count) => `${count} evento${count === 1 ? '' : 's'}`,
|
|
42
|
+
moreEvents: (count) => `+${count} mas`,
|
|
43
|
+
};
|
|
44
|
+
function defaultCalendarLocale() {
|
|
45
|
+
return typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en-US';
|
|
46
|
+
}
|
|
47
|
+
function defaultCalendarLabels(locale) {
|
|
48
|
+
return locale.toLowerCase().startsWith('es') ? ES_CALENDAR_LABELS : EN_CALENDAR_LABELS;
|
|
49
|
+
}
|
|
50
|
+
class NeuCalendarComponent {
|
|
51
|
+
events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
|
|
52
|
+
view = input('month', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
|
|
53
|
+
selectedDate = input(new Date(), ...(ngDevMode ? [{ debugName: "selectedDate" }] : /* istanbul ignore next */ []));
|
|
54
|
+
locale = input(defaultCalendarLocale(), ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
55
|
+
maxVisibleEvents = input(3, ...(ngDevMode ? [{ debugName: "maxVisibleEvents" }] : /* istanbul ignore next */ []));
|
|
56
|
+
showHeader = input(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : /* istanbul ignore next */ []));
|
|
57
|
+
labels = input({}, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
|
|
58
|
+
selectedDateChange = output();
|
|
59
|
+
dateSelect = output();
|
|
60
|
+
eventClick = output();
|
|
61
|
+
_selectedDate = signal(startOfDay(new Date()), ...(ngDevMode ? [{ debugName: "_selectedDate" }] : /* istanbul ignore next */ []));
|
|
62
|
+
resolvedLabels = computed(() => ({
|
|
63
|
+
...defaultCalendarLabels(this.locale()),
|
|
64
|
+
...this.labels(),
|
|
65
|
+
}), ...(ngDevMode ? [{ debugName: "resolvedLabels" }] : /* istanbul ignore next */ []));
|
|
66
|
+
normalizedEvents = computed(() => this.events()
|
|
67
|
+
.map((event) => ({
|
|
68
|
+
...event,
|
|
69
|
+
start: this.coerceDate(event.start),
|
|
70
|
+
end: event.end ? this.coerceDate(event.end) : undefined,
|
|
71
|
+
}))
|
|
72
|
+
.sort((a, b) => a.start.getTime() - b.start.getTime()), ...(ngDevMode ? [{ debugName: "normalizedEvents" }] : /* istanbul ignore next */ []));
|
|
73
|
+
weekdays = computed(() => {
|
|
74
|
+
const base = startOfWeek(new Date(2026, 0, 5));
|
|
75
|
+
return Array.from({ length: 7 }, (_, index) => new Intl.DateTimeFormat(this.locale(), { weekday: 'short' }).format(addDays(base, index)));
|
|
76
|
+
}, ...(ngDevMode ? [{ debugName: "weekdays" }] : /* istanbul ignore next */ []));
|
|
77
|
+
monthDays = computed(() => {
|
|
78
|
+
const selected = this._selectedDate();
|
|
79
|
+
const firstDayOfMonth = new Date(selected.getFullYear(), selected.getMonth(), 1);
|
|
80
|
+
const gridStart = startOfWeek(firstDayOfMonth);
|
|
81
|
+
return Array.from({ length: 42 }, (_, index) => {
|
|
82
|
+
const date = addDays(gridStart, index);
|
|
83
|
+
return this.buildDayCell(date, date.getMonth() === selected.getMonth());
|
|
84
|
+
});
|
|
85
|
+
}, ...(ngDevMode ? [{ debugName: "monthDays" }] : /* istanbul ignore next */ []));
|
|
86
|
+
weekDays = computed(() => {
|
|
87
|
+
const start = startOfWeek(this._selectedDate());
|
|
88
|
+
return Array.from({ length: 7 }, (_, index) => this.buildDayCell(addDays(start, index), true));
|
|
89
|
+
}, ...(ngDevMode ? [{ debugName: "weekDays" }] : /* istanbul ignore next */ []));
|
|
90
|
+
selectedDay = computed(() => this.buildDayCell(this._selectedDate(), true), ...(ngDevMode ? [{ debugName: "selectedDay" }] : /* istanbul ignore next */ []));
|
|
91
|
+
selectedDayEvents = computed(() => this.selectedDay().events, ...(ngDevMode ? [{ debugName: "selectedDayEvents" }] : /* istanbul ignore next */ []));
|
|
92
|
+
selectedAgendaLabel = computed(() => new Intl.DateTimeFormat(this.locale(), {
|
|
93
|
+
weekday: 'long',
|
|
94
|
+
month: 'long',
|
|
95
|
+
day: 'numeric',
|
|
96
|
+
}).format(this._selectedDate()), ...(ngDevMode ? [{ debugName: "selectedAgendaLabel" }] : /* istanbul ignore next */ []));
|
|
97
|
+
currentLabel = computed(() => {
|
|
98
|
+
const selected = this._selectedDate();
|
|
99
|
+
if (this.view() === 'month') {
|
|
100
|
+
return new Intl.DateTimeFormat(this.locale(), { month: 'long', year: 'numeric' }).format(selected);
|
|
101
|
+
}
|
|
102
|
+
const weekStart = startOfWeek(selected);
|
|
103
|
+
const weekEnd = addDays(weekStart, 6);
|
|
104
|
+
const formatter = new Intl.DateTimeFormat(this.locale(), { month: 'short', day: 'numeric' });
|
|
105
|
+
return `${formatter.format(weekStart)} - ${formatter.format(weekEnd)}`;
|
|
106
|
+
}, ...(ngDevMode ? [{ debugName: "currentLabel" }] : /* istanbul ignore next */ []));
|
|
107
|
+
constructor() {
|
|
108
|
+
effect(() => {
|
|
109
|
+
this._selectedDate.set(this.coerceDate(this.selectedDate()));
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
prev() {
|
|
113
|
+
this.selectDate(this.view() === 'month'
|
|
114
|
+
? addMonths(this._selectedDate(), -1)
|
|
115
|
+
: addDays(this._selectedDate(), -7));
|
|
116
|
+
}
|
|
117
|
+
next() {
|
|
118
|
+
this.selectDate(this.view() === 'month'
|
|
119
|
+
? addMonths(this._selectedDate(), 1)
|
|
120
|
+
: addDays(this._selectedDate(), 7));
|
|
121
|
+
}
|
|
122
|
+
today() {
|
|
123
|
+
this.selectDate(new Date());
|
|
124
|
+
}
|
|
125
|
+
selectDate(date) {
|
|
126
|
+
const nextDate = startOfDay(date);
|
|
127
|
+
this._selectedDate.set(nextDate);
|
|
128
|
+
this.selectedDateChange.emit(nextDate);
|
|
129
|
+
this.dateSelect.emit(nextDate);
|
|
130
|
+
}
|
|
131
|
+
visibleEvents(events) {
|
|
132
|
+
return events.slice(0, this.maxVisibleEvents());
|
|
133
|
+
}
|
|
134
|
+
monthVisibleEvents(events) {
|
|
135
|
+
return events.slice(0, this.monthVisibleEventLimit(events.length));
|
|
136
|
+
}
|
|
137
|
+
formatEventMeta(event) {
|
|
138
|
+
if (event.meta)
|
|
139
|
+
return event.meta;
|
|
140
|
+
if (event.allDay)
|
|
141
|
+
return this.resolvedLabels().allDay;
|
|
142
|
+
return new Intl.DateTimeFormat(this.locale(), {
|
|
143
|
+
hour: '2-digit',
|
|
144
|
+
minute: '2-digit',
|
|
145
|
+
}).format(event.start);
|
|
146
|
+
}
|
|
147
|
+
eventTooltip(event) {
|
|
148
|
+
const meta = this.formatEventMeta(event);
|
|
149
|
+
return meta ? `${event.title} · ${meta}` : event.title;
|
|
150
|
+
}
|
|
151
|
+
formatWeekDate(date) {
|
|
152
|
+
return new Intl.DateTimeFormat(this.locale(), { month: 'short', day: 'numeric' }).format(date);
|
|
153
|
+
}
|
|
154
|
+
formatDayAriaLabel(day) {
|
|
155
|
+
const dateLabel = new Intl.DateTimeFormat(this.locale(), {
|
|
156
|
+
weekday: 'long',
|
|
157
|
+
month: 'long',
|
|
158
|
+
day: 'numeric',
|
|
159
|
+
year: 'numeric',
|
|
160
|
+
}).format(day.date);
|
|
161
|
+
const eventLabel = this.resolvedLabels().eventCount(day.events.length);
|
|
162
|
+
return `${dateLabel}, ${eventLabel}`;
|
|
163
|
+
}
|
|
164
|
+
onDaySpace(event, date) {
|
|
165
|
+
event.preventDefault();
|
|
166
|
+
this.selectDate(date);
|
|
167
|
+
}
|
|
168
|
+
onDayKeydown(event, date) {
|
|
169
|
+
if (event.key === 'Enter') {
|
|
170
|
+
event.preventDefault();
|
|
171
|
+
this.selectDate(date);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (event.key === ' ' || event.key === 'Spacebar') {
|
|
175
|
+
this.onDaySpace(event, date);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
onEventClick(event, calendarEvent) {
|
|
179
|
+
event.stopPropagation();
|
|
180
|
+
this.eventClick.emit({
|
|
181
|
+
...calendarEvent,
|
|
182
|
+
start: new Date(calendarEvent.start),
|
|
183
|
+
end: calendarEvent.end ? new Date(calendarEvent.end) : undefined,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
buildDayCell(date, inCurrentMonth) {
|
|
187
|
+
const normalizedDate = startOfDay(date);
|
|
188
|
+
const today = startOfDay(new Date());
|
|
189
|
+
return {
|
|
190
|
+
date: normalizedDate,
|
|
191
|
+
inCurrentMonth,
|
|
192
|
+
isToday: sameDay(normalizedDate, today),
|
|
193
|
+
isSelected: sameDay(normalizedDate, this._selectedDate()),
|
|
194
|
+
events: this.normalizedEvents().filter((event) => sameDay(event.start, normalizedDate)),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
monthVisibleEventLimit(eventCount) {
|
|
198
|
+
const limit = this.maxVisibleEvents();
|
|
199
|
+
if (eventCount <= limit || limit <= 1) {
|
|
200
|
+
return limit;
|
|
201
|
+
}
|
|
202
|
+
return limit - 1;
|
|
203
|
+
}
|
|
204
|
+
coerceDate(value) {
|
|
205
|
+
const candidate = value instanceof Date ? value : new Date(value);
|
|
206
|
+
return Number.isNaN(candidate.getTime()) ? startOfDay(new Date()) : startOfDay(candidate);
|
|
207
|
+
}
|
|
208
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
209
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuCalendarComponent, isStandalone: true, selector: "neu-calendar", inputs: { events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleEvents: { classPropertyName: "maxVisibleEvents", publicName: "maxVisibleEvents", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedDateChange: "selectedDateChange", dateSelect: "dateSelect", eventClick: "eventClick" }, ngImport: i0, template: `
|
|
210
|
+
<div
|
|
211
|
+
class="neu-calendar"
|
|
212
|
+
[class.neu-calendar--month]="view() === 'month'"
|
|
213
|
+
[class.neu-calendar--week]="view() === 'week'"
|
|
214
|
+
>
|
|
215
|
+
@if (showHeader()) {
|
|
216
|
+
<header class="neu-calendar__header">
|
|
217
|
+
<div>
|
|
218
|
+
<h3 class="neu-calendar__title">{{ currentLabel() }}</h3>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<div class="neu-calendar__nav">
|
|
222
|
+
<button
|
|
223
|
+
type="button"
|
|
224
|
+
class="neu-calendar__nav-btn"
|
|
225
|
+
[attr.aria-label]="resolvedLabels().previousButtonAriaLabel"
|
|
226
|
+
(click)="prev()"
|
|
227
|
+
>
|
|
228
|
+
‹
|
|
229
|
+
</button>
|
|
230
|
+
<button type="button" class="neu-calendar__today" (click)="today()">
|
|
231
|
+
{{ resolvedLabels().todayButton }}
|
|
232
|
+
</button>
|
|
233
|
+
<button
|
|
234
|
+
type="button"
|
|
235
|
+
class="neu-calendar__nav-btn"
|
|
236
|
+
[attr.aria-label]="resolvedLabels().nextButtonAriaLabel"
|
|
237
|
+
(click)="next()"
|
|
238
|
+
>
|
|
239
|
+
›
|
|
240
|
+
</button>
|
|
241
|
+
</div>
|
|
242
|
+
</header>
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
<div class="neu-calendar__viewport">
|
|
246
|
+
<div class="neu-calendar__weekdays">
|
|
247
|
+
@for (weekday of weekdays(); track $index) {
|
|
248
|
+
<div class="neu-calendar__weekday">{{ weekday }}</div>
|
|
249
|
+
}
|
|
250
|
+
</div>
|
|
251
|
+
|
|
252
|
+
@if (view() === 'month') {
|
|
253
|
+
<div class="neu-calendar__month-grid">
|
|
254
|
+
@for (day of monthDays(); track day.date.toISOString()) {
|
|
255
|
+
<article
|
|
256
|
+
class="neu-calendar__day"
|
|
257
|
+
tabindex="0"
|
|
258
|
+
role="button"
|
|
259
|
+
[attr.aria-label]="formatDayAriaLabel(day)"
|
|
260
|
+
[class.neu-calendar__day--outside]="!day.inCurrentMonth"
|
|
261
|
+
[class.neu-calendar__day--today]="day.isToday"
|
|
262
|
+
[class.neu-calendar__day--selected]="day.isSelected"
|
|
263
|
+
(click)="selectDate(day.date)"
|
|
264
|
+
(keydown)="onDayKeydown($event, day.date)"
|
|
265
|
+
>
|
|
266
|
+
<div class="neu-calendar__day-top">
|
|
267
|
+
<span class="neu-calendar__day-number">{{ day.date.getDate() }}</span>
|
|
268
|
+
@if (day.events.length > 0) {
|
|
269
|
+
<span class="neu-calendar__day-count">{{ day.events.length }}</span>
|
|
270
|
+
}
|
|
271
|
+
</div>
|
|
272
|
+
<div class="neu-calendar__event-list">
|
|
273
|
+
@for (event of monthVisibleEvents(day.events); track event.id) {
|
|
274
|
+
<button
|
|
275
|
+
type="button"
|
|
276
|
+
class="neu-calendar__event neu-calendar__event--compact"
|
|
277
|
+
[class]="
|
|
278
|
+
'neu-calendar__event neu-calendar__event--compact neu-calendar__event--' +
|
|
279
|
+
(event.variant || 'default')
|
|
280
|
+
"
|
|
281
|
+
[attr.title]="eventTooltip(event)"
|
|
282
|
+
[attr.aria-label]="eventTooltip(event)"
|
|
283
|
+
(click)="onEventClick($event, event)"
|
|
284
|
+
>
|
|
285
|
+
<span class="neu-calendar__event-title">{{ event.title }}</span>
|
|
286
|
+
<span class="neu-calendar__event-meta">{{ formatEventMeta(event) }}</span>
|
|
287
|
+
</button>
|
|
288
|
+
}
|
|
289
|
+
</div>
|
|
290
|
+
</article>
|
|
291
|
+
}
|
|
292
|
+
</div>
|
|
293
|
+
} @else {
|
|
294
|
+
<div class="neu-calendar__week-grid">
|
|
295
|
+
@for (day of weekDays(); track day.date.toISOString()) {
|
|
296
|
+
<article
|
|
297
|
+
class="neu-calendar__week-day"
|
|
298
|
+
tabindex="0"
|
|
299
|
+
role="button"
|
|
300
|
+
[attr.aria-label]="formatDayAriaLabel(day)"
|
|
301
|
+
[class.neu-calendar__day--today]="day.isToday"
|
|
302
|
+
[class.neu-calendar__day--selected]="day.isSelected"
|
|
303
|
+
(click)="selectDate(day.date)"
|
|
304
|
+
(keydown)="onDayKeydown($event, day.date)"
|
|
305
|
+
>
|
|
306
|
+
<div class="neu-calendar__week-head">
|
|
307
|
+
<span class="neu-calendar__day-number">{{ day.date.getDate() }}</span>
|
|
308
|
+
<span class="neu-calendar__week-date">{{ formatWeekDate(day.date) }}</span>
|
|
309
|
+
</div>
|
|
310
|
+
|
|
311
|
+
<div class="neu-calendar__week-events">
|
|
312
|
+
@if (day.events.length === 0) {
|
|
313
|
+
<p class="neu-calendar__empty">{{ resolvedLabels().noEvents }}</p>
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
@for (event of visibleEvents(day.events); track event.id) {
|
|
317
|
+
<button
|
|
318
|
+
type="button"
|
|
319
|
+
class="neu-calendar__event"
|
|
320
|
+
[class]="
|
|
321
|
+
'neu-calendar__event neu-calendar__event--' + (event.variant || 'default')
|
|
322
|
+
"
|
|
323
|
+
[attr.title]="eventTooltip(event)"
|
|
324
|
+
[attr.aria-label]="eventTooltip(event)"
|
|
325
|
+
(click)="onEventClick($event, event)"
|
|
326
|
+
>
|
|
327
|
+
<span class="neu-calendar__event-title">{{ event.title }}</span>
|
|
328
|
+
<span class="neu-calendar__event-meta">{{ formatEventMeta(event) }}</span>
|
|
329
|
+
</button>
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@if (day.events.length > maxVisibleEvents()) {
|
|
333
|
+
<span class="neu-calendar__more">{{
|
|
334
|
+
resolvedLabels().moreEvents(day.events.length - maxVisibleEvents())
|
|
335
|
+
}}</span>
|
|
336
|
+
}
|
|
337
|
+
</div>
|
|
338
|
+
</article>
|
|
339
|
+
}
|
|
340
|
+
</div>
|
|
341
|
+
}
|
|
342
|
+
</div>
|
|
343
|
+
|
|
344
|
+
<section class="neu-calendar__agenda" aria-live="polite">
|
|
345
|
+
<div class="neu-calendar__agenda-header">
|
|
346
|
+
<h4 class="neu-calendar__agenda-title">{{ selectedAgendaLabel() }}</h4>
|
|
347
|
+
<span class="neu-calendar__agenda-count">{{
|
|
348
|
+
resolvedLabels().eventCount(selectedDayEvents().length)
|
|
349
|
+
}}</span>
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
@if (selectedDayEvents().length === 0) {
|
|
353
|
+
<p class="neu-calendar__agenda-empty">{{ resolvedLabels().noEvents }}</p>
|
|
354
|
+
} @else {
|
|
355
|
+
<div class="neu-calendar__agenda-list">
|
|
356
|
+
@for (event of selectedDayEvents(); track event.id) {
|
|
357
|
+
<button
|
|
358
|
+
type="button"
|
|
359
|
+
class="neu-calendar__agenda-event neu-calendar__event neu-calendar__event--{{
|
|
360
|
+
event.variant || 'default'
|
|
361
|
+
}}"
|
|
362
|
+
[attr.title]="eventTooltip(event)"
|
|
363
|
+
[attr.aria-label]="eventTooltip(event)"
|
|
364
|
+
(click)="onEventClick($event, event)"
|
|
365
|
+
>
|
|
366
|
+
<span class="neu-calendar__event-title">{{ event.title }}</span>
|
|
367
|
+
<span class="neu-calendar__event-meta">{{ formatEventMeta(event) }}</span>
|
|
368
|
+
</button>
|
|
369
|
+
}
|
|
370
|
+
</div>
|
|
371
|
+
}
|
|
372
|
+
</section>
|
|
373
|
+
</div>
|
|
374
|
+
`, isInline: true, styles: [".neu-calendar{display:grid;gap:var(--neu-space-4);padding:var(--neu-space-4);overflow:hidden;border-radius:calc(var(--neu-radius-lg) + 4px);background:radial-gradient(circle at top left,color-mix(in srgb,var(--neu-primary) 6%,transparent 94%),transparent 30%),linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 82%,var(--neu-surface) 18%),var(--neu-surface));border:1px solid color-mix(in srgb,var(--neu-border) 92%,transparent 8%);box-shadow:var(--neu-shadow-sm)}.neu-calendar--month .neu-calendar__weekdays,.neu-calendar--month .neu-calendar__month-grid{min-width:800px}.neu-calendar--month .neu-calendar__month-grid{grid-auto-rows:172px}.neu-calendar--month .neu-calendar__day{min-height:0;height:100%}.neu-calendar--month .neu-calendar__event-list{max-height:100%}.neu-calendar--week .neu-calendar__weekdays,.neu-calendar--week .neu-calendar__week-grid{min-width:0}.neu-calendar__viewport{display:grid;gap:8px;overflow-x:auto;overflow-y:hidden;min-width:0;scrollbar-gutter:stable}.neu-calendar__viewport{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--neu-border) 88%,transparent 12%) transparent}.neu-calendar__viewport::-webkit-scrollbar{height:8px}.neu-calendar__viewport::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px}.neu-calendar__header{display:flex;align-items:center;justify-content:space-between;gap:var(--neu-space-4);flex-wrap:wrap}.neu-calendar__nav{display:inline-flex;align-items:center;gap:var(--neu-space-2)}.neu-calendar__title{margin:0;font-size:clamp(1.05rem,1vw + .9rem,1.35rem);font-weight:700;color:var(--neu-text);text-transform:capitalize}.neu-calendar__nav-btn{min-width:36px;height:36px;border:1px solid color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px;background:color-mix(in srgb,var(--neu-surface) 88%,var(--neu-surface-2) 12%);color:var(--neu-text);cursor:pointer;transition:transform var(--neu-transition),border-color var(--neu-transition),background var(--neu-transition)}.neu-calendar__nav-btn:hover,.neu-calendar__today:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--neu-primary) 45%,var(--neu-border) 55%)}.neu-calendar__today{height:36px;padding:0 var(--neu-space-3);border:1px solid color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px;background:color-mix(in srgb,var(--neu-surface-2) 92%,var(--neu-surface) 8%);color:var(--neu-text);cursor:pointer;font-weight:600;transition:transform var(--neu-transition),border-color var(--neu-transition),background var(--neu-transition)}.neu-calendar__weekdays,.neu-calendar__month-grid,.neu-calendar__week-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;background:transparent;border:none;border-radius:0;overflow:visible}.neu-calendar__weekday{padding:0 8px 6px;text-align:center;background:transparent;color:var(--neu-text-muted);font-size:var(--neu-text-xs);font-weight:700;text-transform:uppercase;letter-spacing:.04em}.neu-calendar__day{min-height:110px;padding:10px;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-radius:18px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface) 96%,var(--neu-surface-2) 4%),color-mix(in srgb,var(--neu-surface) 88%,black 12%));display:grid;grid-template-rows:auto minmax(0,1fr);align-content:start;gap:var(--neu-space-2);cursor:pointer;text-align:left;box-sizing:border-box;min-width:0;overflow:hidden;box-shadow:0 12px 24px -24px color-mix(in srgb,black 32%,transparent 68%),inset 0 1px color-mix(in srgb,white 8%,transparent 92%);transition:background var(--neu-transition),box-shadow var(--neu-transition),border-color var(--neu-transition),transform var(--neu-transition)}.neu-calendar__day--outside{background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 90%,black 10%),color-mix(in srgb,var(--neu-surface-2) 82%,black 18%));box-shadow:none;opacity:.72}.neu-calendar__day--today{border-color:color-mix(in srgb,var(--neu-primary) 36%,var(--neu-border) 64%);background:linear-gradient(180deg,color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface) 90%),color-mix(in srgb,var(--neu-primary) 6%,var(--neu-surface) 94%));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 22%,transparent 78%),0 12px 26px -24px color-mix(in srgb,var(--neu-primary) 18%,transparent 82%)}.neu-calendar__day--selected{background:linear-gradient(180deg,color-mix(in srgb,var(--neu-primary) 14%,var(--neu-surface) 86%),color-mix(in srgb,var(--neu-primary) 8%,var(--neu-surface) 92%));border-color:color-mix(in srgb,var(--neu-primary) 38%,var(--neu-border) 62%);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 22%,transparent 78%),0 12px 24px -24px color-mix(in srgb,var(--neu-primary) 18%,transparent 82%)}.neu-calendar__day:hover,.neu-calendar__week-day:hover{background:color-mix(in srgb,var(--neu-primary) 4%,var(--neu-surface) 96%);border-color:color-mix(in srgb,var(--neu-primary) 22%,var(--neu-border) 78%);transform:translateY(-1px)}.neu-calendar__day:focus-visible,.neu-calendar__week-day:focus-visible,.neu-calendar__event:focus-visible,.neu-calendar__nav-btn:focus-visible,.neu-calendar__today:focus-visible{outline:2px solid color-mix(in srgb,var(--neu-primary) 75%,white 25%);outline-offset:-2px}.neu-calendar__day-top{display:flex;align-items:center;justify-content:space-between;gap:var(--neu-space-2);min-width:0}.neu-calendar__day-count{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;background:color-mix(in srgb,var(--neu-surface-2) 72%,black 28%);color:color-mix(in srgb,var(--neu-text-muted) 72%,var(--neu-text) 28%);font-size:11px;font-weight:700;flex-shrink:0}.neu-calendar__day-number{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:999px;font-size:var(--neu-text-sm);color:var(--neu-text)}.neu-calendar__day--selected .neu-calendar__day-number{background:var(--neu-primary);color:#fff}.neu-calendar__event-list{display:grid;gap:4px;align-content:start;overflow-x:hidden;overflow-y:auto;min-height:0;min-width:0;width:100%;padding-right:2px;scrollbar-gutter:stable}.neu-calendar__event-list{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--neu-border) 88%,transparent 12%) transparent}.neu-calendar__event-list::-webkit-scrollbar{width:6px}.neu-calendar__event-list::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px}.neu-calendar__event{display:grid;gap:2px;width:100%;justify-self:stretch;align-self:start;padding:8px;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-left:2px solid var(--neu-primary);border-radius:14px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 46%,var(--neu-surface) 54%),color-mix(in srgb,var(--neu-surface) 74%,black 26%));text-align:left;cursor:pointer;box-shadow:inset 0 1px color-mix(in srgb,white 6%,transparent 94%),0 10px 18px -20px color-mix(in srgb,black 34%,transparent 66%);min-width:0;box-sizing:border-box;max-width:100%;overflow:hidden}.neu-calendar__event--compact{gap:1px;padding:5px 6px;border-radius:12px;box-shadow:none}.neu-calendar__event--compact .neu-calendar__event-title,.neu-calendar__event--compact .neu-calendar__event-meta{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-calendar__event--compact .neu-calendar__event-title{font-size:11px}.neu-calendar__event--compact .neu-calendar__event-meta{font-size:10px}.neu-calendar__event--default{border-left-color:var(--neu-primary)}.neu-calendar__event--success{border-left-color:var(--neu-success)}.neu-calendar__event--warning{border-left-color:var(--neu-warning)}.neu-calendar__event--danger{border-left-color:var(--neu-danger)}.neu-calendar__event--info{border-left-color:#0ea5e9}.neu-calendar__event-title{font-size:var(--neu-text-xs);font-weight:700;color:var(--neu-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-calendar__event-meta{font-size:11px;color:var(--neu-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-calendar__more{display:inline-flex;align-items:center;justify-content:center;min-height:28px;width:100%;padding:0 8px;border-radius:12px;border:1px dashed color-mix(in srgb,var(--neu-border) 92%,transparent 8%);background:color-mix(in srgb,var(--neu-surface-2) 72%,var(--neu-surface) 28%);font-size:11px;color:var(--neu-text-muted);box-sizing:border-box}.neu-calendar__more--summary{font-weight:700;letter-spacing:.01em}.neu-calendar__agenda{display:grid;gap:var(--neu-space-3);padding:14px;min-width:0;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-radius:18px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface) 94%,var(--neu-surface-2) 6%),color-mix(in srgb,var(--neu-surface) 86%,black 14%));box-shadow:0 12px 24px -24px color-mix(in srgb,black 28%,transparent 72%),inset 0 1px color-mix(in srgb,white 8%,transparent 92%)}.neu-calendar__agenda-header{display:flex;align-items:center;justify-content:space-between;gap:var(--neu-space-3);flex-wrap:wrap}.neu-calendar__agenda-title{margin:0;font-size:var(--neu-text-base);font-weight:700;color:var(--neu-text);text-transform:capitalize}.neu-calendar__agenda-count{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;border-radius:999px;background:color-mix(in srgb,var(--neu-surface-2) 72%,black 28%);color:var(--neu-text-muted);font-size:11px;font-weight:700}.neu-calendar__agenda-list{display:grid;gap:8px}.neu-calendar__agenda-event{min-height:48px}.neu-calendar__agenda-empty{margin:0;color:var(--neu-text-muted);font-size:var(--neu-text-sm)}.neu-calendar__week-day{min-height:220px;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-radius:18px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface) 94%,var(--neu-surface-2) 6%),color-mix(in srgb,var(--neu-surface) 84%,black 16%));display:grid;grid-template-rows:auto 1fr;text-align:left;box-sizing:border-box;min-width:0;overflow:hidden;box-shadow:0 12px 24px -24px color-mix(in srgb,black 32%,transparent 68%),inset 0 1px color-mix(in srgb,white 8%,transparent 92%)}.neu-calendar__week-head{display:grid;gap:4px;padding:14px 12px 12px;border-bottom:1px solid color-mix(in srgb,var(--neu-border) 90%,transparent 10%);background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 78%,transparent 22%),transparent);border-radius:18px 18px 0 0}.neu-calendar__week-date{font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-calendar__week-events{scrollbar-width:none}.neu-calendar__week-events::-webkit-scrollbar{display:none}.neu-calendar__week-events{padding:12px;display:grid;align-content:start;gap:var(--neu-space-2);overflow:hidden;min-height:0;min-width:0}.neu-calendar__empty{margin:0;font-size:var(--neu-text-sm);color:var(--neu-text-muted);line-height:1.35}@media(max-width:860px){.neu-calendar{padding:var(--neu-space-3)}.neu-calendar--month .neu-calendar__weekdays,.neu-calendar--month .neu-calendar__month-grid{min-width:760px}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
375
|
+
}
|
|
376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuCalendarComponent, decorators: [{
|
|
377
|
+
type: Component,
|
|
378
|
+
args: [{ selector: 'neu-calendar', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
379
|
+
<div
|
|
380
|
+
class="neu-calendar"
|
|
381
|
+
[class.neu-calendar--month]="view() === 'month'"
|
|
382
|
+
[class.neu-calendar--week]="view() === 'week'"
|
|
383
|
+
>
|
|
384
|
+
@if (showHeader()) {
|
|
385
|
+
<header class="neu-calendar__header">
|
|
386
|
+
<div>
|
|
387
|
+
<h3 class="neu-calendar__title">{{ currentLabel() }}</h3>
|
|
388
|
+
</div>
|
|
389
|
+
|
|
390
|
+
<div class="neu-calendar__nav">
|
|
391
|
+
<button
|
|
392
|
+
type="button"
|
|
393
|
+
class="neu-calendar__nav-btn"
|
|
394
|
+
[attr.aria-label]="resolvedLabels().previousButtonAriaLabel"
|
|
395
|
+
(click)="prev()"
|
|
396
|
+
>
|
|
397
|
+
‹
|
|
398
|
+
</button>
|
|
399
|
+
<button type="button" class="neu-calendar__today" (click)="today()">
|
|
400
|
+
{{ resolvedLabels().todayButton }}
|
|
401
|
+
</button>
|
|
402
|
+
<button
|
|
403
|
+
type="button"
|
|
404
|
+
class="neu-calendar__nav-btn"
|
|
405
|
+
[attr.aria-label]="resolvedLabels().nextButtonAriaLabel"
|
|
406
|
+
(click)="next()"
|
|
407
|
+
>
|
|
408
|
+
›
|
|
409
|
+
</button>
|
|
410
|
+
</div>
|
|
411
|
+
</header>
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
<div class="neu-calendar__viewport">
|
|
415
|
+
<div class="neu-calendar__weekdays">
|
|
416
|
+
@for (weekday of weekdays(); track $index) {
|
|
417
|
+
<div class="neu-calendar__weekday">{{ weekday }}</div>
|
|
418
|
+
}
|
|
419
|
+
</div>
|
|
420
|
+
|
|
421
|
+
@if (view() === 'month') {
|
|
422
|
+
<div class="neu-calendar__month-grid">
|
|
423
|
+
@for (day of monthDays(); track day.date.toISOString()) {
|
|
424
|
+
<article
|
|
425
|
+
class="neu-calendar__day"
|
|
426
|
+
tabindex="0"
|
|
427
|
+
role="button"
|
|
428
|
+
[attr.aria-label]="formatDayAriaLabel(day)"
|
|
429
|
+
[class.neu-calendar__day--outside]="!day.inCurrentMonth"
|
|
430
|
+
[class.neu-calendar__day--today]="day.isToday"
|
|
431
|
+
[class.neu-calendar__day--selected]="day.isSelected"
|
|
432
|
+
(click)="selectDate(day.date)"
|
|
433
|
+
(keydown)="onDayKeydown($event, day.date)"
|
|
434
|
+
>
|
|
435
|
+
<div class="neu-calendar__day-top">
|
|
436
|
+
<span class="neu-calendar__day-number">{{ day.date.getDate() }}</span>
|
|
437
|
+
@if (day.events.length > 0) {
|
|
438
|
+
<span class="neu-calendar__day-count">{{ day.events.length }}</span>
|
|
439
|
+
}
|
|
440
|
+
</div>
|
|
441
|
+
<div class="neu-calendar__event-list">
|
|
442
|
+
@for (event of monthVisibleEvents(day.events); track event.id) {
|
|
443
|
+
<button
|
|
444
|
+
type="button"
|
|
445
|
+
class="neu-calendar__event neu-calendar__event--compact"
|
|
446
|
+
[class]="
|
|
447
|
+
'neu-calendar__event neu-calendar__event--compact neu-calendar__event--' +
|
|
448
|
+
(event.variant || 'default')
|
|
449
|
+
"
|
|
450
|
+
[attr.title]="eventTooltip(event)"
|
|
451
|
+
[attr.aria-label]="eventTooltip(event)"
|
|
452
|
+
(click)="onEventClick($event, event)"
|
|
453
|
+
>
|
|
454
|
+
<span class="neu-calendar__event-title">{{ event.title }}</span>
|
|
455
|
+
<span class="neu-calendar__event-meta">{{ formatEventMeta(event) }}</span>
|
|
456
|
+
</button>
|
|
457
|
+
}
|
|
458
|
+
</div>
|
|
459
|
+
</article>
|
|
460
|
+
}
|
|
461
|
+
</div>
|
|
462
|
+
} @else {
|
|
463
|
+
<div class="neu-calendar__week-grid">
|
|
464
|
+
@for (day of weekDays(); track day.date.toISOString()) {
|
|
465
|
+
<article
|
|
466
|
+
class="neu-calendar__week-day"
|
|
467
|
+
tabindex="0"
|
|
468
|
+
role="button"
|
|
469
|
+
[attr.aria-label]="formatDayAriaLabel(day)"
|
|
470
|
+
[class.neu-calendar__day--today]="day.isToday"
|
|
471
|
+
[class.neu-calendar__day--selected]="day.isSelected"
|
|
472
|
+
(click)="selectDate(day.date)"
|
|
473
|
+
(keydown)="onDayKeydown($event, day.date)"
|
|
474
|
+
>
|
|
475
|
+
<div class="neu-calendar__week-head">
|
|
476
|
+
<span class="neu-calendar__day-number">{{ day.date.getDate() }}</span>
|
|
477
|
+
<span class="neu-calendar__week-date">{{ formatWeekDate(day.date) }}</span>
|
|
478
|
+
</div>
|
|
479
|
+
|
|
480
|
+
<div class="neu-calendar__week-events">
|
|
481
|
+
@if (day.events.length === 0) {
|
|
482
|
+
<p class="neu-calendar__empty">{{ resolvedLabels().noEvents }}</p>
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
@for (event of visibleEvents(day.events); track event.id) {
|
|
486
|
+
<button
|
|
487
|
+
type="button"
|
|
488
|
+
class="neu-calendar__event"
|
|
489
|
+
[class]="
|
|
490
|
+
'neu-calendar__event neu-calendar__event--' + (event.variant || 'default')
|
|
491
|
+
"
|
|
492
|
+
[attr.title]="eventTooltip(event)"
|
|
493
|
+
[attr.aria-label]="eventTooltip(event)"
|
|
494
|
+
(click)="onEventClick($event, event)"
|
|
495
|
+
>
|
|
496
|
+
<span class="neu-calendar__event-title">{{ event.title }}</span>
|
|
497
|
+
<span class="neu-calendar__event-meta">{{ formatEventMeta(event) }}</span>
|
|
498
|
+
</button>
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
@if (day.events.length > maxVisibleEvents()) {
|
|
502
|
+
<span class="neu-calendar__more">{{
|
|
503
|
+
resolvedLabels().moreEvents(day.events.length - maxVisibleEvents())
|
|
504
|
+
}}</span>
|
|
505
|
+
}
|
|
506
|
+
</div>
|
|
507
|
+
</article>
|
|
508
|
+
}
|
|
509
|
+
</div>
|
|
510
|
+
}
|
|
511
|
+
</div>
|
|
512
|
+
|
|
513
|
+
<section class="neu-calendar__agenda" aria-live="polite">
|
|
514
|
+
<div class="neu-calendar__agenda-header">
|
|
515
|
+
<h4 class="neu-calendar__agenda-title">{{ selectedAgendaLabel() }}</h4>
|
|
516
|
+
<span class="neu-calendar__agenda-count">{{
|
|
517
|
+
resolvedLabels().eventCount(selectedDayEvents().length)
|
|
518
|
+
}}</span>
|
|
519
|
+
</div>
|
|
520
|
+
|
|
521
|
+
@if (selectedDayEvents().length === 0) {
|
|
522
|
+
<p class="neu-calendar__agenda-empty">{{ resolvedLabels().noEvents }}</p>
|
|
523
|
+
} @else {
|
|
524
|
+
<div class="neu-calendar__agenda-list">
|
|
525
|
+
@for (event of selectedDayEvents(); track event.id) {
|
|
526
|
+
<button
|
|
527
|
+
type="button"
|
|
528
|
+
class="neu-calendar__agenda-event neu-calendar__event neu-calendar__event--{{
|
|
529
|
+
event.variant || 'default'
|
|
530
|
+
}}"
|
|
531
|
+
[attr.title]="eventTooltip(event)"
|
|
532
|
+
[attr.aria-label]="eventTooltip(event)"
|
|
533
|
+
(click)="onEventClick($event, event)"
|
|
534
|
+
>
|
|
535
|
+
<span class="neu-calendar__event-title">{{ event.title }}</span>
|
|
536
|
+
<span class="neu-calendar__event-meta">{{ formatEventMeta(event) }}</span>
|
|
537
|
+
</button>
|
|
538
|
+
}
|
|
539
|
+
</div>
|
|
540
|
+
}
|
|
541
|
+
</section>
|
|
542
|
+
</div>
|
|
543
|
+
`, styles: [".neu-calendar{display:grid;gap:var(--neu-space-4);padding:var(--neu-space-4);overflow:hidden;border-radius:calc(var(--neu-radius-lg) + 4px);background:radial-gradient(circle at top left,color-mix(in srgb,var(--neu-primary) 6%,transparent 94%),transparent 30%),linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 82%,var(--neu-surface) 18%),var(--neu-surface));border:1px solid color-mix(in srgb,var(--neu-border) 92%,transparent 8%);box-shadow:var(--neu-shadow-sm)}.neu-calendar--month .neu-calendar__weekdays,.neu-calendar--month .neu-calendar__month-grid{min-width:800px}.neu-calendar--month .neu-calendar__month-grid{grid-auto-rows:172px}.neu-calendar--month .neu-calendar__day{min-height:0;height:100%}.neu-calendar--month .neu-calendar__event-list{max-height:100%}.neu-calendar--week .neu-calendar__weekdays,.neu-calendar--week .neu-calendar__week-grid{min-width:0}.neu-calendar__viewport{display:grid;gap:8px;overflow-x:auto;overflow-y:hidden;min-width:0;scrollbar-gutter:stable}.neu-calendar__viewport{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--neu-border) 88%,transparent 12%) transparent}.neu-calendar__viewport::-webkit-scrollbar{height:8px}.neu-calendar__viewport::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px}.neu-calendar__header{display:flex;align-items:center;justify-content:space-between;gap:var(--neu-space-4);flex-wrap:wrap}.neu-calendar__nav{display:inline-flex;align-items:center;gap:var(--neu-space-2)}.neu-calendar__title{margin:0;font-size:clamp(1.05rem,1vw + .9rem,1.35rem);font-weight:700;color:var(--neu-text);text-transform:capitalize}.neu-calendar__nav-btn{min-width:36px;height:36px;border:1px solid color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px;background:color-mix(in srgb,var(--neu-surface) 88%,var(--neu-surface-2) 12%);color:var(--neu-text);cursor:pointer;transition:transform var(--neu-transition),border-color var(--neu-transition),background var(--neu-transition)}.neu-calendar__nav-btn:hover,.neu-calendar__today:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--neu-primary) 45%,var(--neu-border) 55%)}.neu-calendar__today{height:36px;padding:0 var(--neu-space-3);border:1px solid color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px;background:color-mix(in srgb,var(--neu-surface-2) 92%,var(--neu-surface) 8%);color:var(--neu-text);cursor:pointer;font-weight:600;transition:transform var(--neu-transition),border-color var(--neu-transition),background var(--neu-transition)}.neu-calendar__weekdays,.neu-calendar__month-grid,.neu-calendar__week-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;background:transparent;border:none;border-radius:0;overflow:visible}.neu-calendar__weekday{padding:0 8px 6px;text-align:center;background:transparent;color:var(--neu-text-muted);font-size:var(--neu-text-xs);font-weight:700;text-transform:uppercase;letter-spacing:.04em}.neu-calendar__day{min-height:110px;padding:10px;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-radius:18px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface) 96%,var(--neu-surface-2) 4%),color-mix(in srgb,var(--neu-surface) 88%,black 12%));display:grid;grid-template-rows:auto minmax(0,1fr);align-content:start;gap:var(--neu-space-2);cursor:pointer;text-align:left;box-sizing:border-box;min-width:0;overflow:hidden;box-shadow:0 12px 24px -24px color-mix(in srgb,black 32%,transparent 68%),inset 0 1px color-mix(in srgb,white 8%,transparent 92%);transition:background var(--neu-transition),box-shadow var(--neu-transition),border-color var(--neu-transition),transform var(--neu-transition)}.neu-calendar__day--outside{background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 90%,black 10%),color-mix(in srgb,var(--neu-surface-2) 82%,black 18%));box-shadow:none;opacity:.72}.neu-calendar__day--today{border-color:color-mix(in srgb,var(--neu-primary) 36%,var(--neu-border) 64%);background:linear-gradient(180deg,color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface) 90%),color-mix(in srgb,var(--neu-primary) 6%,var(--neu-surface) 94%));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 22%,transparent 78%),0 12px 26px -24px color-mix(in srgb,var(--neu-primary) 18%,transparent 82%)}.neu-calendar__day--selected{background:linear-gradient(180deg,color-mix(in srgb,var(--neu-primary) 14%,var(--neu-surface) 86%),color-mix(in srgb,var(--neu-primary) 8%,var(--neu-surface) 92%));border-color:color-mix(in srgb,var(--neu-primary) 38%,var(--neu-border) 62%);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 22%,transparent 78%),0 12px 24px -24px color-mix(in srgb,var(--neu-primary) 18%,transparent 82%)}.neu-calendar__day:hover,.neu-calendar__week-day:hover{background:color-mix(in srgb,var(--neu-primary) 4%,var(--neu-surface) 96%);border-color:color-mix(in srgb,var(--neu-primary) 22%,var(--neu-border) 78%);transform:translateY(-1px)}.neu-calendar__day:focus-visible,.neu-calendar__week-day:focus-visible,.neu-calendar__event:focus-visible,.neu-calendar__nav-btn:focus-visible,.neu-calendar__today:focus-visible{outline:2px solid color-mix(in srgb,var(--neu-primary) 75%,white 25%);outline-offset:-2px}.neu-calendar__day-top{display:flex;align-items:center;justify-content:space-between;gap:var(--neu-space-2);min-width:0}.neu-calendar__day-count{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;background:color-mix(in srgb,var(--neu-surface-2) 72%,black 28%);color:color-mix(in srgb,var(--neu-text-muted) 72%,var(--neu-text) 28%);font-size:11px;font-weight:700;flex-shrink:0}.neu-calendar__day-number{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:999px;font-size:var(--neu-text-sm);color:var(--neu-text)}.neu-calendar__day--selected .neu-calendar__day-number{background:var(--neu-primary);color:#fff}.neu-calendar__event-list{display:grid;gap:4px;align-content:start;overflow-x:hidden;overflow-y:auto;min-height:0;min-width:0;width:100%;padding-right:2px;scrollbar-gutter:stable}.neu-calendar__event-list{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--neu-border) 88%,transparent 12%) transparent}.neu-calendar__event-list::-webkit-scrollbar{width:6px}.neu-calendar__event-list::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--neu-border) 88%,transparent 12%);border-radius:999px}.neu-calendar__event{display:grid;gap:2px;width:100%;justify-self:stretch;align-self:start;padding:8px;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-left:2px solid var(--neu-primary);border-radius:14px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 46%,var(--neu-surface) 54%),color-mix(in srgb,var(--neu-surface) 74%,black 26%));text-align:left;cursor:pointer;box-shadow:inset 0 1px color-mix(in srgb,white 6%,transparent 94%),0 10px 18px -20px color-mix(in srgb,black 34%,transparent 66%);min-width:0;box-sizing:border-box;max-width:100%;overflow:hidden}.neu-calendar__event--compact{gap:1px;padding:5px 6px;border-radius:12px;box-shadow:none}.neu-calendar__event--compact .neu-calendar__event-title,.neu-calendar__event--compact .neu-calendar__event-meta{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-calendar__event--compact .neu-calendar__event-title{font-size:11px}.neu-calendar__event--compact .neu-calendar__event-meta{font-size:10px}.neu-calendar__event--default{border-left-color:var(--neu-primary)}.neu-calendar__event--success{border-left-color:var(--neu-success)}.neu-calendar__event--warning{border-left-color:var(--neu-warning)}.neu-calendar__event--danger{border-left-color:var(--neu-danger)}.neu-calendar__event--info{border-left-color:#0ea5e9}.neu-calendar__event-title{font-size:var(--neu-text-xs);font-weight:700;color:var(--neu-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-calendar__event-meta{font-size:11px;color:var(--neu-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-calendar__more{display:inline-flex;align-items:center;justify-content:center;min-height:28px;width:100%;padding:0 8px;border-radius:12px;border:1px dashed color-mix(in srgb,var(--neu-border) 92%,transparent 8%);background:color-mix(in srgb,var(--neu-surface-2) 72%,var(--neu-surface) 28%);font-size:11px;color:var(--neu-text-muted);box-sizing:border-box}.neu-calendar__more--summary{font-weight:700;letter-spacing:.01em}.neu-calendar__agenda{display:grid;gap:var(--neu-space-3);padding:14px;min-width:0;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-radius:18px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface) 94%,var(--neu-surface-2) 6%),color-mix(in srgb,var(--neu-surface) 86%,black 14%));box-shadow:0 12px 24px -24px color-mix(in srgb,black 28%,transparent 72%),inset 0 1px color-mix(in srgb,white 8%,transparent 92%)}.neu-calendar__agenda-header{display:flex;align-items:center;justify-content:space-between;gap:var(--neu-space-3);flex-wrap:wrap}.neu-calendar__agenda-title{margin:0;font-size:var(--neu-text-base);font-weight:700;color:var(--neu-text);text-transform:capitalize}.neu-calendar__agenda-count{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;border-radius:999px;background:color-mix(in srgb,var(--neu-surface-2) 72%,black 28%);color:var(--neu-text-muted);font-size:11px;font-weight:700}.neu-calendar__agenda-list{display:grid;gap:8px}.neu-calendar__agenda-event{min-height:48px}.neu-calendar__agenda-empty{margin:0;color:var(--neu-text-muted);font-size:var(--neu-text-sm)}.neu-calendar__week-day{min-height:220px;border:1px solid color-mix(in srgb,var(--neu-border) 94%,transparent 6%);border-radius:18px;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface) 94%,var(--neu-surface-2) 6%),color-mix(in srgb,var(--neu-surface) 84%,black 16%));display:grid;grid-template-rows:auto 1fr;text-align:left;box-sizing:border-box;min-width:0;overflow:hidden;box-shadow:0 12px 24px -24px color-mix(in srgb,black 32%,transparent 68%),inset 0 1px color-mix(in srgb,white 8%,transparent 92%)}.neu-calendar__week-head{display:grid;gap:4px;padding:14px 12px 12px;border-bottom:1px solid color-mix(in srgb,var(--neu-border) 90%,transparent 10%);background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 78%,transparent 22%),transparent);border-radius:18px 18px 0 0}.neu-calendar__week-date{font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-calendar__week-events{scrollbar-width:none}.neu-calendar__week-events::-webkit-scrollbar{display:none}.neu-calendar__week-events{padding:12px;display:grid;align-content:start;gap:var(--neu-space-2);overflow:hidden;min-height:0;min-width:0}.neu-calendar__empty{margin:0;font-size:var(--neu-text-sm);color:var(--neu-text-muted);line-height:1.35}@media(max-width:860px){.neu-calendar{padding:var(--neu-space-3)}.neu-calendar--month .neu-calendar__weekdays,.neu-calendar--month .neu-calendar__month-grid{min-width:760px}}\n"] }]
|
|
544
|
+
}], ctorParameters: () => [], propDecorators: { events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], selectedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedDate", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], maxVisibleEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisibleEvents", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], selectedDateChange: [{ type: i0.Output, args: ["selectedDateChange"] }], dateSelect: [{ type: i0.Output, args: ["dateSelect"] }], eventClick: [{ type: i0.Output, args: ["eventClick"] }] } });
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Generated bundle index. Do not edit.
|
|
548
|
+
*/
|
|
549
|
+
|
|
550
|
+
export { NeuCalendarComponent };
|
|
551
|
+
//# sourceMappingURL=neural-ui-core-calendar.mjs.map
|