@ngstarter-ui/components 21.0.9 → 21.0.10
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.
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"generatedBy": "scripts/generate-ai-metadata.mjs",
|
|
4
4
|
"package": "@ngstarter-ui/components",
|
|
5
5
|
"description": "AI-readable registry for NgStarter UI Angular secondary entry points.",
|
|
6
|
-
"componentCount":
|
|
6
|
+
"componentCount": 121,
|
|
7
7
|
"conventions": {
|
|
8
8
|
"importPattern": "@ngstarter-ui/components/<component>",
|
|
9
9
|
"selectorPrefix": "ngs",
|
|
@@ -1063,6 +1063,117 @@
|
|
|
1063
1063
|
],
|
|
1064
1064
|
"example": null
|
|
1065
1065
|
},
|
|
1066
|
+
{
|
|
1067
|
+
"name": "calendar",
|
|
1068
|
+
"title": "Calendar",
|
|
1069
|
+
"overviewName": "Calendar",
|
|
1070
|
+
"category": "components",
|
|
1071
|
+
"package": "@ngstarter-ui/components",
|
|
1072
|
+
"importPath": "@ngstarter-ui/components/calendar",
|
|
1073
|
+
"publicApi": "projects/components/calendar/public-api.ts",
|
|
1074
|
+
"sourceRoot": "projects/components/calendar/src",
|
|
1075
|
+
"docsPath": "/components/calendar",
|
|
1076
|
+
"docsOverviewSource": "projects/docs/src/app/components/calendar/overview/overview.html",
|
|
1077
|
+
"purpose": "The NgStarter Angular Calendar component renders an inline month calendar for dashboards, scheduling widgets, event summaries, availability previews, and date-driven product surfaces.",
|
|
1078
|
+
"useWhen": "Choose Calendar when the workflow matches examples such as Basic Calendar, Calendar With Events, Calendar With Min And Max Dates, Calendar min max.",
|
|
1079
|
+
"exampleTopics": [
|
|
1080
|
+
"Basic Calendar",
|
|
1081
|
+
"Calendar With Events",
|
|
1082
|
+
"Calendar With Min And Max Dates",
|
|
1083
|
+
"Calendar min max"
|
|
1084
|
+
],
|
|
1085
|
+
"minimalExample": "<div class=\"calendar-example\">\n <ngs-calendar [selected]=\"selectedDate()\" (selectedChange)=\"selectedDate.set($event)\" />\n</div>",
|
|
1086
|
+
"exampleFiles": [
|
|
1087
|
+
{
|
|
1088
|
+
"name": "basic-calendar-example",
|
|
1089
|
+
"title": "Basic calendar",
|
|
1090
|
+
"file": "projects/docs/src/app/components/calendar/_examples/basic-calendar-example/basic-calendar-example.html",
|
|
1091
|
+
"source": "<div class=\"calendar-example\">\n <ngs-calendar [selected]=\"selectedDate()\" (selectedChange)=\"selectedDate.set($event)\" />\n</div>"
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
"name": "calendar-min-max-example",
|
|
1095
|
+
"title": "Calendar min max",
|
|
1096
|
+
"file": "projects/docs/src/app/components/calendar/_examples/calendar-min-max-example/calendar-min-max-example.html",
|
|
1097
|
+
"source": "<div class=\"calendar-example\">\n <ngs-calendar\n [selected]=\"selectedDate()\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [firstDayOfWeek]=\"1\"\n [showAdjacentDays]=\"false\"\n (selectedChange)=\"selectedDate.set($event)\"\n />\n</div>"
|
|
1098
|
+
},
|
|
1099
|
+
{
|
|
1100
|
+
"name": "calendar-with-events-example",
|
|
1101
|
+
"title": "Calendar with events",
|
|
1102
|
+
"file": "projects/docs/src/app/components/calendar/_examples/calendar-with-events-example/calendar-with-events-example.html",
|
|
1103
|
+
"source": "<div class=\"calendar-example\">\n <ngs-calendar\n [selected]=\"selectedDate()\"\n [events]=\"events\"\n [showEventTitles]=\"true\"\n (selectedChange)=\"selectedDate.set($event)\"\n />\n</div>"
|
|
1104
|
+
}
|
|
1105
|
+
],
|
|
1106
|
+
"previewAsset": null,
|
|
1107
|
+
"selectors": [
|
|
1108
|
+
"ngs-calendar"
|
|
1109
|
+
],
|
|
1110
|
+
"exportedSymbols": [
|
|
1111
|
+
"Calendar",
|
|
1112
|
+
"CalendarDateInput",
|
|
1113
|
+
"CalendarEvent",
|
|
1114
|
+
"CalendarEventColor"
|
|
1115
|
+
],
|
|
1116
|
+
"inputs": [
|
|
1117
|
+
"events",
|
|
1118
|
+
"firstDayOfWeek",
|
|
1119
|
+
"locale",
|
|
1120
|
+
"maxDate",
|
|
1121
|
+
"minDate",
|
|
1122
|
+
"selected",
|
|
1123
|
+
"showAdjacentDays",
|
|
1124
|
+
"showEventTitles",
|
|
1125
|
+
"showTodayButton",
|
|
1126
|
+
"startAt"
|
|
1127
|
+
],
|
|
1128
|
+
"outputs": [
|
|
1129
|
+
"eventSelected",
|
|
1130
|
+
"monthChange",
|
|
1131
|
+
"selectedChange"
|
|
1132
|
+
],
|
|
1133
|
+
"cssTokens": [
|
|
1134
|
+
"--ngs-button-bg",
|
|
1135
|
+
"--ngs-button-border-radius",
|
|
1136
|
+
"--ngs-button-height",
|
|
1137
|
+
"--ngs-button-padding",
|
|
1138
|
+
"--ngs-button-padding-x",
|
|
1139
|
+
"--ngs-calendar-day-bg",
|
|
1140
|
+
"--ngs-calendar-day-hover-bg",
|
|
1141
|
+
"--ngs-calendar-day-min-height",
|
|
1142
|
+
"--ngs-calendar-day-muted-color",
|
|
1143
|
+
"--ngs-calendar-day-radius",
|
|
1144
|
+
"--ngs-calendar-day-selected-bg",
|
|
1145
|
+
"--ngs-calendar-day-selected-color",
|
|
1146
|
+
"--ngs-calendar-day-today-outline",
|
|
1147
|
+
"--ngs-calendar-event-blue",
|
|
1148
|
+
"--ngs-calendar-event-danger",
|
|
1149
|
+
"--ngs-calendar-event-green",
|
|
1150
|
+
"--ngs-calendar-event-info",
|
|
1151
|
+
"--ngs-calendar-event-neutral",
|
|
1152
|
+
"--ngs-calendar-event-primary",
|
|
1153
|
+
"--ngs-calendar-event-rose",
|
|
1154
|
+
"--ngs-calendar-event-success",
|
|
1155
|
+
"--ngs-calendar-event-warning",
|
|
1156
|
+
"--ngs-calendar-gap",
|
|
1157
|
+
"--ngs-calendar-header-gap",
|
|
1158
|
+
"--ngs-calendar-header-margin-bottom",
|
|
1159
|
+
"--ngs-calendar-weekday-color",
|
|
1160
|
+
"--ngs-color-danger",
|
|
1161
|
+
"--ngs-color-info",
|
|
1162
|
+
"--ngs-color-on-primary",
|
|
1163
|
+
"--ngs-color-on-surface",
|
|
1164
|
+
"--ngs-color-on-surface-variant",
|
|
1165
|
+
"--ngs-color-outline",
|
|
1166
|
+
"--ngs-color-primary",
|
|
1167
|
+
"--ngs-color-success",
|
|
1168
|
+
"--ngs-color-surface-container",
|
|
1169
|
+
"--ngs-color-warning",
|
|
1170
|
+
"--ngs-font-size-lg",
|
|
1171
|
+
"--ngs-font-size-xs",
|
|
1172
|
+
"--ngs-radius-md",
|
|
1173
|
+
"--ngs-radius-sm"
|
|
1174
|
+
],
|
|
1175
|
+
"example": null
|
|
1176
|
+
},
|
|
1066
1177
|
{
|
|
1067
1178
|
"name": "card",
|
|
1068
1179
|
"title": "Card",
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, numberAttribute, booleanAttribute, output, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { Button } from '@ngstarter-ui/components/button';
|
|
4
|
+
import { Icon } from '@ngstarter-ui/components/icon';
|
|
5
|
+
|
|
6
|
+
class Calendar {
|
|
7
|
+
startAt = input(null, ...(ngDevMode ? [{ debugName: "startAt" }] : /* istanbul ignore next */ []));
|
|
8
|
+
selected = input(null, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
9
|
+
minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
|
|
10
|
+
maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
|
|
11
|
+
events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
|
|
12
|
+
locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
13
|
+
firstDayOfWeek = input(0, { ...(ngDevMode ? { debugName: "firstDayOfWeek" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
14
|
+
showAdjacentDays = input(true, { ...(ngDevMode ? { debugName: "showAdjacentDays" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
15
|
+
showTodayButton = input(true, { ...(ngDevMode ? { debugName: "showTodayButton" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
16
|
+
showEventTitles = input(false, { ...(ngDevMode ? { debugName: "showEventTitles" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
17
|
+
selectedChange = output();
|
|
18
|
+
monthChange = output();
|
|
19
|
+
eventSelected = output();
|
|
20
|
+
activeMonth = signal(this.getInitialActiveMonth(), ...(ngDevMode ? [{ debugName: "activeMonth" }] : /* istanbul ignore next */ []));
|
|
21
|
+
selectedDate = signal(this.normalizeDateInput(this.selected()), ...(ngDevMode ? [{ debugName: "selectedDate" }] : /* istanbul ignore next */ []));
|
|
22
|
+
normalizedMinDate = computed(() => this.normalizeDateInput(this.minDate()), ...(ngDevMode ? [{ debugName: "normalizedMinDate" }] : /* istanbul ignore next */ []));
|
|
23
|
+
normalizedMaxDate = computed(() => this.normalizeDateInput(this.maxDate()), ...(ngDevMode ? [{ debugName: "normalizedMaxDate" }] : /* istanbul ignore next */ []));
|
|
24
|
+
periodLabel = computed(() => new Intl.DateTimeFormat(this.locale(), {
|
|
25
|
+
month: 'long',
|
|
26
|
+
year: 'numeric',
|
|
27
|
+
}).format(this.activeMonth()), ...(ngDevMode ? [{ debugName: "periodLabel" }] : /* istanbul ignore next */ []));
|
|
28
|
+
weekdayLabels = computed(() => {
|
|
29
|
+
const formatter = new Intl.DateTimeFormat(this.locale(), { weekday: 'short' });
|
|
30
|
+
const labels = [];
|
|
31
|
+
const weekStart = this.normalizedFirstDayOfWeek();
|
|
32
|
+
for (let index = 0; index < 7; index++) {
|
|
33
|
+
const date = new Date(2024, 0, 7 + weekStart + index);
|
|
34
|
+
labels.push(formatter.format(date));
|
|
35
|
+
}
|
|
36
|
+
return labels;
|
|
37
|
+
}, ...(ngDevMode ? [{ debugName: "weekdayLabels" }] : /* istanbul ignore next */ []));
|
|
38
|
+
calendarCells = computed(() => {
|
|
39
|
+
const activeMonth = this.activeMonth();
|
|
40
|
+
const selectedDate = this.selectedDate();
|
|
41
|
+
const minDate = this.normalizedMinDate();
|
|
42
|
+
const maxDate = this.normalizedMaxDate();
|
|
43
|
+
const showAdjacentDays = this.showAdjacentDays();
|
|
44
|
+
const monthStart = this.startOfMonth(activeMonth);
|
|
45
|
+
const weekStart = this.normalizedFirstDayOfWeek();
|
|
46
|
+
const firstDayOffset = (monthStart.getDay() - weekStart + 7) % 7;
|
|
47
|
+
const gridStart = this.addDays(monthStart, -firstDayOffset);
|
|
48
|
+
const today = this.startOfDay(new Date());
|
|
49
|
+
const eventMap = this.eventsByDate();
|
|
50
|
+
const cells = [];
|
|
51
|
+
for (let index = 0; index < 42; index++) {
|
|
52
|
+
const date = this.addDays(gridStart, index);
|
|
53
|
+
const inCurrentMonth = this.sameMonth(date, activeMonth);
|
|
54
|
+
const events = eventMap.get(this.dateKey(date)) ?? [];
|
|
55
|
+
const visible = inCurrentMonth || showAdjacentDays;
|
|
56
|
+
cells.push({
|
|
57
|
+
date,
|
|
58
|
+
key: this.dateKey(date),
|
|
59
|
+
label: visible ? String(date.getDate()) : '',
|
|
60
|
+
ariaLabel: this.formatFullDate(date),
|
|
61
|
+
inCurrentMonth,
|
|
62
|
+
visible,
|
|
63
|
+
today: this.sameDate(date, today),
|
|
64
|
+
selected: !!selectedDate && this.sameDate(date, selectedDate),
|
|
65
|
+
disabled: this.isDisabled(date, minDate, maxDate) || !visible,
|
|
66
|
+
events,
|
|
67
|
+
markers: this.uniqueEventColors(events),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return cells;
|
|
71
|
+
}, ...(ngDevMode ? [{ debugName: "calendarCells" }] : /* istanbul ignore next */ []));
|
|
72
|
+
constructor() {
|
|
73
|
+
effect(() => {
|
|
74
|
+
const selected = this.normalizeDateInput(this.selected());
|
|
75
|
+
this.selectedDate.set(selected);
|
|
76
|
+
if (selected) {
|
|
77
|
+
this.activeMonth.set(this.startOfMonth(selected));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
effect(() => {
|
|
81
|
+
const startAt = this.normalizeDateInput(this.startAt());
|
|
82
|
+
if (startAt) {
|
|
83
|
+
this.activeMonth.set(this.startOfMonth(startAt));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
previousMonth() {
|
|
88
|
+
this.setActiveMonth(this.addMonths(this.activeMonth(), -1));
|
|
89
|
+
}
|
|
90
|
+
nextMonth() {
|
|
91
|
+
this.setActiveMonth(this.addMonths(this.activeMonth(), 1));
|
|
92
|
+
}
|
|
93
|
+
selectToday() {
|
|
94
|
+
const today = this.startOfDay(new Date());
|
|
95
|
+
this.setActiveMonth(today);
|
|
96
|
+
if (!this.isDisabled(today, this.normalizedMinDate(), this.normalizedMaxDate())) {
|
|
97
|
+
this.selectDate(today);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
selectCell(cell) {
|
|
101
|
+
if (cell.disabled) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (!cell.inCurrentMonth) {
|
|
105
|
+
this.setActiveMonth(cell.date);
|
|
106
|
+
}
|
|
107
|
+
this.selectDate(cell.date);
|
|
108
|
+
}
|
|
109
|
+
selectEvent(event, domEvent) {
|
|
110
|
+
domEvent.stopPropagation();
|
|
111
|
+
this.eventSelected.emit(event);
|
|
112
|
+
}
|
|
113
|
+
markerClass(color) {
|
|
114
|
+
return `ngs-calendar-event-${color}`;
|
|
115
|
+
}
|
|
116
|
+
selectDate(date) {
|
|
117
|
+
const value = this.startOfDay(date);
|
|
118
|
+
this.selectedDate.set(value);
|
|
119
|
+
this.selectedChange.emit(this.cloneDate(value));
|
|
120
|
+
}
|
|
121
|
+
setActiveMonth(date) {
|
|
122
|
+
const month = this.startOfMonth(date);
|
|
123
|
+
this.activeMonth.set(month);
|
|
124
|
+
this.monthChange.emit(this.cloneDate(month));
|
|
125
|
+
}
|
|
126
|
+
getInitialActiveMonth() {
|
|
127
|
+
return this.startOfMonth(this.normalizeDateInput(this.selected()) ??
|
|
128
|
+
this.normalizeDateInput(this.startAt()) ??
|
|
129
|
+
new Date());
|
|
130
|
+
}
|
|
131
|
+
eventsByDate() {
|
|
132
|
+
const map = new Map();
|
|
133
|
+
for (const event of this.events()) {
|
|
134
|
+
const date = this.normalizeDateInput(event.date);
|
|
135
|
+
if (!date) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const key = this.dateKey(date);
|
|
139
|
+
const events = map.get(key) ?? [];
|
|
140
|
+
events.push(event);
|
|
141
|
+
map.set(key, events);
|
|
142
|
+
}
|
|
143
|
+
return map;
|
|
144
|
+
}
|
|
145
|
+
uniqueEventColors(events) {
|
|
146
|
+
const colors = new Set();
|
|
147
|
+
for (const event of events) {
|
|
148
|
+
colors.add(event.color ?? 'primary');
|
|
149
|
+
}
|
|
150
|
+
return [...colors].slice(0, 3);
|
|
151
|
+
}
|
|
152
|
+
normalizedFirstDayOfWeek() {
|
|
153
|
+
const value = this.firstDayOfWeek();
|
|
154
|
+
if (!Number.isFinite(value)) {
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
return ((Math.trunc(value) % 7) + 7) % 7;
|
|
158
|
+
}
|
|
159
|
+
normalizeDateInput(value) {
|
|
160
|
+
if (value === null || value === undefined || value === '') {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
if (value instanceof Date) {
|
|
164
|
+
return Number.isNaN(value.getTime()) ? null : this.startOfDay(value);
|
|
165
|
+
}
|
|
166
|
+
if (typeof value === 'string') {
|
|
167
|
+
const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
168
|
+
if (dateOnly) {
|
|
169
|
+
const year = Number(dateOnly[1]);
|
|
170
|
+
const month = Number(dateOnly[2]) - 1;
|
|
171
|
+
const day = Number(dateOnly[3]);
|
|
172
|
+
const date = new Date(year, month, day);
|
|
173
|
+
return Number.isNaN(date.getTime()) ? null : this.startOfDay(date);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const date = new Date(value);
|
|
177
|
+
return Number.isNaN(date.getTime()) ? null : this.startOfDay(date);
|
|
178
|
+
}
|
|
179
|
+
isDisabled(date, minDate, maxDate) {
|
|
180
|
+
return ((!!minDate && this.compareDate(date, minDate) < 0) ||
|
|
181
|
+
(!!maxDate && this.compareDate(date, maxDate) > 0));
|
|
182
|
+
}
|
|
183
|
+
formatFullDate(date) {
|
|
184
|
+
return new Intl.DateTimeFormat(this.locale(), {
|
|
185
|
+
weekday: 'long',
|
|
186
|
+
month: 'long',
|
|
187
|
+
day: 'numeric',
|
|
188
|
+
year: 'numeric',
|
|
189
|
+
}).format(date);
|
|
190
|
+
}
|
|
191
|
+
addMonths(date, months) {
|
|
192
|
+
return new Date(date.getFullYear(), date.getMonth() + months, 1);
|
|
193
|
+
}
|
|
194
|
+
addDays(date, days) {
|
|
195
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
|
|
196
|
+
}
|
|
197
|
+
startOfMonth(date) {
|
|
198
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
199
|
+
}
|
|
200
|
+
startOfDay(date) {
|
|
201
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
202
|
+
}
|
|
203
|
+
cloneDate(date) {
|
|
204
|
+
return new Date(date.getTime());
|
|
205
|
+
}
|
|
206
|
+
sameMonth(first, second) {
|
|
207
|
+
return first.getFullYear() === second.getFullYear() && first.getMonth() === second.getMonth();
|
|
208
|
+
}
|
|
209
|
+
sameDate(first, second) {
|
|
210
|
+
return this.compareDate(first, second) === 0;
|
|
211
|
+
}
|
|
212
|
+
compareDate(first, second) {
|
|
213
|
+
return (first.getFullYear() - second.getFullYear() ||
|
|
214
|
+
first.getMonth() - second.getMonth() ||
|
|
215
|
+
first.getDate() - second.getDate());
|
|
216
|
+
}
|
|
217
|
+
dateKey(date) {
|
|
218
|
+
const year = date.getFullYear();
|
|
219
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
220
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
221
|
+
return `${year}-${month}-${day}`;
|
|
222
|
+
}
|
|
223
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Calendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
224
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: Calendar, isStandalone: true, selector: "ngs-calendar", inputs: { startAt: { classPropertyName: "startAt", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, showAdjacentDays: { classPropertyName: "showAdjacentDays", publicName: "showAdjacentDays", isSignal: true, isRequired: false, transformFunction: null }, showTodayButton: { classPropertyName: "showTodayButton", publicName: "showTodayButton", isSignal: true, isRequired: false, transformFunction: null }, showEventTitles: { classPropertyName: "showEventTitles", publicName: "showEventTitles", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedChange: "selectedChange", monthChange: "monthChange", eventSelected: "eventSelected" }, host: { classAttribute: "ngs-calendar" }, exportAs: ["ngsCalendar"], ngImport: i0, template: "<div class=\"ngs-calendar-header\">\n <button\n ngsIconButton\n type=\"button\"\n class=\"ngs-calendar-previous-button\"\n aria-label=\"Previous month\"\n (click)=\"previousMonth()\"\n >\n <ngs-icon name=\"fluent:chevron-left-24-regular\" />\n </button>\n\n <div class=\"ngs-calendar-period\" aria-live=\"polite\">{{ periodLabel() }}</div>\n\n <div class=\"ngs-calendar-actions\">\n @if (showTodayButton()) {\n <button ngsButton type=\"button\" class=\"ngs-calendar-today-button\" (click)=\"selectToday()\">\n Today\n </button>\n }\n\n <button\n ngsIconButton\n type=\"button\"\n class=\"ngs-calendar-next-button\"\n aria-label=\"Next month\"\n (click)=\"nextMonth()\"\n >\n <ngs-icon name=\"fluent:chevron-right-24-regular\" />\n </button>\n </div>\n</div>\n\n<div class=\"ngs-calendar-weekdays\" role=\"row\">\n @for (weekday of weekdayLabels(); track weekday) {\n <div class=\"ngs-calendar-weekday\" role=\"columnheader\">{{ weekday }}</div>\n }\n</div>\n\n<div class=\"ngs-calendar-grid\" role=\"grid\" [attr.aria-label]=\"periodLabel()\">\n @for (cell of calendarCells(); track cell.key) {\n <button\n ngsButton\n type=\"button\"\n class=\"ngs-calendar-day\"\n [class.ngs-calendar-day-hidden]=\"!cell.visible\"\n [class.ngs-calendar-day-muted]=\"!cell.inCurrentMonth\"\n [class.ngs-calendar-day-today]=\"cell.today\"\n [class.ngs-calendar-day-selected]=\"cell.selected\"\n [class.ngs-calendar-day-has-events]=\"cell.events.length > 0\"\n [disabled]=\"cell.disabled\"\n [attr.aria-label]=\"cell.ariaLabel\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.data-date]=\"cell.key\"\n role=\"gridcell\"\n (click)=\"selectCell(cell)\"\n >\n <span class=\"ngs-calendar-day-number\">{{ cell.label }}</span>\n\n @if (cell.markers.length > 0) {\n <span class=\"ngs-calendar-event-markers\" aria-hidden=\"true\">\n @for (marker of cell.markers; track marker) {\n <span class=\"ngs-calendar-event-marker {{ markerClass(marker) }}\"></span>\n }\n </span>\n }\n\n @if (showEventTitles() && cell.events.length > 0) {\n <span class=\"ngs-calendar-event-list\">\n @for (event of cell.events.slice(0, 2); track event.id ?? event.title ?? $index) {\n <span class=\"ngs-calendar-event-title\" (click)=\"selectEvent(event, $event)\">\n {{ event.title }}\n </span>\n }\n </span>\n }\n </button>\n }\n</div>\n", styles: [":host{--ngs-calendar-gap: calc(var(--spacing, .25rem) * 1);--ngs-calendar-header-gap: calc(var(--spacing, .25rem) * 2);--ngs-calendar-day-min-height: calc(var(--spacing, .25rem) * 12);--ngs-calendar-day-radius: var(--ngs-radius-md);--ngs-calendar-day-bg: transparent;--ngs-calendar-day-hover-bg: var(--ngs-color-surface-container);--ngs-calendar-day-selected-bg: var(--ngs-color-primary);--ngs-calendar-day-selected-color: var(--ngs-color-on-primary);--ngs-calendar-day-today-outline: 1px solid var(--ngs-color-primary);--ngs-calendar-day-muted-color: var(--ngs-color-on-surface-variant);--ngs-calendar-weekday-color: var(--ngs-color-on-surface-variant);--ngs-calendar-event-primary: var(--ngs-color-primary);--ngs-calendar-event-success: var(--ngs-color-success);--ngs-calendar-event-warning: var(--ngs-color-warning);--ngs-calendar-event-danger: var(--ngs-color-danger);--ngs-calendar-event-info: var(--ngs-color-info);--ngs-calendar-event-neutral: var(--ngs-color-outline);--ngs-calendar-event-green: var(--ngs-color-success);--ngs-calendar-event-rose: var(--ngs-color-danger);--ngs-calendar-event-blue: var(--ngs-color-info);--ngs-calendar-header-margin-bottom: 0;display:flex;flex-direction:column;width:100%;min-width:0;gap:var(--ngs-calendar-gap);color:var(--ngs-color-on-surface)}:host .ngs-calendar-header{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--ngs-calendar-header-gap);min-width:0;margin-bottom:var(--ngs-calendar-header-margin-bottom)}:host .ngs-calendar-period{min-width:0;overflow:hidden;color:var(--ngs-color-on-surface);font-size:var(--ngs-font-size-lg);font-weight:600;text-align:center;text-overflow:ellipsis;white-space:nowrap}:host .ngs-calendar-actions{display:inline-flex;align-items:center;gap:var(--ngs-calendar-header-gap)}:host .ngs-calendar-today-button{--ngs-button-height: calc(var(--spacing, .25rem) * 9);--ngs-button-padding-x: calc(var(--spacing, .25rem) * 3)}:host .ngs-calendar-weekdays,:host .ngs-calendar-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:var(--ngs-calendar-gap)}:host .ngs-calendar-weekday{display:flex;align-items:center;justify-content:center;min-width:0;min-height:calc(var(--spacing, .25rem) * 7);color:var(--ngs-calendar-weekday-color);font-size:var(--ngs-font-size-xs);font-weight:500;text-transform:uppercase}:host .ngs-calendar-grid{flex:1;min-height:0}:host button.ngs-calendar-day{--ngs-button-bg: var(--ngs-calendar-day-bg);--ngs-button-border-radius: var(--ngs-calendar-day-radius);--ngs-button-height: auto;--ngs-button-padding: calc(var(--spacing, .25rem) * 1);position:relative;display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;min-width:0;min-height:var(--ngs-calendar-day-min-height);color:var(--ngs-color-on-surface);font-weight:400;gap:calc(var(--spacing, .25rem) * 1)}:host button.ngs-calendar-day:not(.ngs-calendar-day-has-events){justify-content:center}:host button.ngs-calendar-day:not(.ngs-calendar-day-selected):not(.ngs-button-disabled):hover{--ngs-button-bg: var(--ngs-calendar-day-hover-bg)}:host button.ngs-calendar-day.ngs-calendar-day-muted{color:var(--ngs-calendar-day-muted-color)}:host button.ngs-calendar-day.ngs-calendar-day-hidden{visibility:hidden;pointer-events:none}:host button.ngs-calendar-day.ngs-calendar-day-selected{--ngs-button-bg: var(--ngs-calendar-day-selected-bg);color:var(--ngs-calendar-day-selected-color)}:host button.ngs-calendar-day.ngs-calendar-day-today:not(.ngs-calendar-day-selected){outline:var(--ngs-calendar-day-today-outline);outline-offset:-1px}:host button.ngs-calendar-day ::ng-deep>.content{display:flex;width:100%;max-width:100%;min-width:0;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:inherit;gap:inherit;line-height:normal}:host .ngs-calendar-day-number{display:inline-flex;align-items:center;justify-content:center;width:calc(var(--spacing, .25rem) * 6);height:calc(var(--spacing, .25rem) * 6);line-height:1}:host .ngs-calendar-event-markers{display:inline-flex;max-width:100%;min-height:calc(var(--spacing, .25rem) * 1.5);align-items:center;justify-content:center;gap:2px}:host .ngs-calendar-event-marker{width:calc(var(--spacing, .25rem) * 1.5);height:calc(var(--spacing, .25rem) * 1.5);flex:none;border-radius:999px;background:var(--ngs-calendar-event-primary)}:host .ngs-calendar-event-marker.ngs-calendar-event-success{background:var(--ngs-calendar-event-success)}:host .ngs-calendar-event-marker.ngs-calendar-event-warning{background:var(--ngs-calendar-event-warning)}:host .ngs-calendar-event-marker.ngs-calendar-event-danger{background:var(--ngs-calendar-event-danger)}:host .ngs-calendar-event-marker.ngs-calendar-event-info{background:var(--ngs-calendar-event-info)}:host .ngs-calendar-event-marker.ngs-calendar-event-neutral{background:var(--ngs-calendar-event-neutral)}:host .ngs-calendar-event-marker.ngs-calendar-event-green{background:var(--ngs-calendar-event-green)}:host .ngs-calendar-event-marker.ngs-calendar-event-rose{background:var(--ngs-calendar-event-rose)}:host .ngs-calendar-event-marker.ngs-calendar-event-blue{background:var(--ngs-calendar-event-blue)}:host .ngs-calendar-event-list{display:flex;width:100%;min-width:0;flex-direction:column;gap:2px}:host .ngs-calendar-event-title{display:block;box-sizing:border-box;overflow:hidden;width:100%;max-width:100%;min-width:0;padding-inline:calc(var(--spacing, .25rem) * 1);border-radius:var(--ngs-radius-sm);background:var(--ngs-calendar-event-primary);color:currentColor;font-size:var(--ngs-font-size-xs);font-weight:400;line-height:1.35;text-align:left;text-overflow:ellipsis;white-space:nowrap}@supports (color: color-mix(in lab,red,red)){:host .ngs-calendar-event-title{background:color-mix(in srgb,var(--ngs-calendar-event-primary),transparent 88%)}}:host .ngs-calendar-day-selected .ngs-calendar-event-marker{background:currentColor}:host .ngs-calendar-day-selected .ngs-calendar-event-title{background:currentColor}@supports (color: color-mix(in lab,red,red)){:host .ngs-calendar-day-selected .ngs-calendar-event-title{background:color-mix(in srgb,currentColor,transparent 84%)}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: Button, selector: " button[ngsButton], button[ngsIconButton], a[ngsButton], a[ngsIconButton] ", inputs: ["ngsButton", "ngsIconButton", "loading", "disabled", "disabledInteractive", "disableRipple", "reverse", "fullWidth", "hideTextOnMobile"], exportAs: ["ngsButton"] }, { kind: "component", type: Icon, selector: "ngs-icon", inputs: ["name"], exportAs: ["ngsIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
225
|
+
}
|
|
226
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Calendar, decorators: [{
|
|
227
|
+
type: Component,
|
|
228
|
+
args: [{ selector: 'ngs-calendar', exportAs: 'ngsCalendar', standalone: true, imports: [Button, Icon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
229
|
+
class: 'ngs-calendar',
|
|
230
|
+
}, template: "<div class=\"ngs-calendar-header\">\n <button\n ngsIconButton\n type=\"button\"\n class=\"ngs-calendar-previous-button\"\n aria-label=\"Previous month\"\n (click)=\"previousMonth()\"\n >\n <ngs-icon name=\"fluent:chevron-left-24-regular\" />\n </button>\n\n <div class=\"ngs-calendar-period\" aria-live=\"polite\">{{ periodLabel() }}</div>\n\n <div class=\"ngs-calendar-actions\">\n @if (showTodayButton()) {\n <button ngsButton type=\"button\" class=\"ngs-calendar-today-button\" (click)=\"selectToday()\">\n Today\n </button>\n }\n\n <button\n ngsIconButton\n type=\"button\"\n class=\"ngs-calendar-next-button\"\n aria-label=\"Next month\"\n (click)=\"nextMonth()\"\n >\n <ngs-icon name=\"fluent:chevron-right-24-regular\" />\n </button>\n </div>\n</div>\n\n<div class=\"ngs-calendar-weekdays\" role=\"row\">\n @for (weekday of weekdayLabels(); track weekday) {\n <div class=\"ngs-calendar-weekday\" role=\"columnheader\">{{ weekday }}</div>\n }\n</div>\n\n<div class=\"ngs-calendar-grid\" role=\"grid\" [attr.aria-label]=\"periodLabel()\">\n @for (cell of calendarCells(); track cell.key) {\n <button\n ngsButton\n type=\"button\"\n class=\"ngs-calendar-day\"\n [class.ngs-calendar-day-hidden]=\"!cell.visible\"\n [class.ngs-calendar-day-muted]=\"!cell.inCurrentMonth\"\n [class.ngs-calendar-day-today]=\"cell.today\"\n [class.ngs-calendar-day-selected]=\"cell.selected\"\n [class.ngs-calendar-day-has-events]=\"cell.events.length > 0\"\n [disabled]=\"cell.disabled\"\n [attr.aria-label]=\"cell.ariaLabel\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.data-date]=\"cell.key\"\n role=\"gridcell\"\n (click)=\"selectCell(cell)\"\n >\n <span class=\"ngs-calendar-day-number\">{{ cell.label }}</span>\n\n @if (cell.markers.length > 0) {\n <span class=\"ngs-calendar-event-markers\" aria-hidden=\"true\">\n @for (marker of cell.markers; track marker) {\n <span class=\"ngs-calendar-event-marker {{ markerClass(marker) }}\"></span>\n }\n </span>\n }\n\n @if (showEventTitles() && cell.events.length > 0) {\n <span class=\"ngs-calendar-event-list\">\n @for (event of cell.events.slice(0, 2); track event.id ?? event.title ?? $index) {\n <span class=\"ngs-calendar-event-title\" (click)=\"selectEvent(event, $event)\">\n {{ event.title }}\n </span>\n }\n </span>\n }\n </button>\n }\n</div>\n", styles: [":host{--ngs-calendar-gap: calc(var(--spacing, .25rem) * 1);--ngs-calendar-header-gap: calc(var(--spacing, .25rem) * 2);--ngs-calendar-day-min-height: calc(var(--spacing, .25rem) * 12);--ngs-calendar-day-radius: var(--ngs-radius-md);--ngs-calendar-day-bg: transparent;--ngs-calendar-day-hover-bg: var(--ngs-color-surface-container);--ngs-calendar-day-selected-bg: var(--ngs-color-primary);--ngs-calendar-day-selected-color: var(--ngs-color-on-primary);--ngs-calendar-day-today-outline: 1px solid var(--ngs-color-primary);--ngs-calendar-day-muted-color: var(--ngs-color-on-surface-variant);--ngs-calendar-weekday-color: var(--ngs-color-on-surface-variant);--ngs-calendar-event-primary: var(--ngs-color-primary);--ngs-calendar-event-success: var(--ngs-color-success);--ngs-calendar-event-warning: var(--ngs-color-warning);--ngs-calendar-event-danger: var(--ngs-color-danger);--ngs-calendar-event-info: var(--ngs-color-info);--ngs-calendar-event-neutral: var(--ngs-color-outline);--ngs-calendar-event-green: var(--ngs-color-success);--ngs-calendar-event-rose: var(--ngs-color-danger);--ngs-calendar-event-blue: var(--ngs-color-info);--ngs-calendar-header-margin-bottom: 0;display:flex;flex-direction:column;width:100%;min-width:0;gap:var(--ngs-calendar-gap);color:var(--ngs-color-on-surface)}:host .ngs-calendar-header{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--ngs-calendar-header-gap);min-width:0;margin-bottom:var(--ngs-calendar-header-margin-bottom)}:host .ngs-calendar-period{min-width:0;overflow:hidden;color:var(--ngs-color-on-surface);font-size:var(--ngs-font-size-lg);font-weight:600;text-align:center;text-overflow:ellipsis;white-space:nowrap}:host .ngs-calendar-actions{display:inline-flex;align-items:center;gap:var(--ngs-calendar-header-gap)}:host .ngs-calendar-today-button{--ngs-button-height: calc(var(--spacing, .25rem) * 9);--ngs-button-padding-x: calc(var(--spacing, .25rem) * 3)}:host .ngs-calendar-weekdays,:host .ngs-calendar-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:var(--ngs-calendar-gap)}:host .ngs-calendar-weekday{display:flex;align-items:center;justify-content:center;min-width:0;min-height:calc(var(--spacing, .25rem) * 7);color:var(--ngs-calendar-weekday-color);font-size:var(--ngs-font-size-xs);font-weight:500;text-transform:uppercase}:host .ngs-calendar-grid{flex:1;min-height:0}:host button.ngs-calendar-day{--ngs-button-bg: var(--ngs-calendar-day-bg);--ngs-button-border-radius: var(--ngs-calendar-day-radius);--ngs-button-height: auto;--ngs-button-padding: calc(var(--spacing, .25rem) * 1);position:relative;display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;min-width:0;min-height:var(--ngs-calendar-day-min-height);color:var(--ngs-color-on-surface);font-weight:400;gap:calc(var(--spacing, .25rem) * 1)}:host button.ngs-calendar-day:not(.ngs-calendar-day-has-events){justify-content:center}:host button.ngs-calendar-day:not(.ngs-calendar-day-selected):not(.ngs-button-disabled):hover{--ngs-button-bg: var(--ngs-calendar-day-hover-bg)}:host button.ngs-calendar-day.ngs-calendar-day-muted{color:var(--ngs-calendar-day-muted-color)}:host button.ngs-calendar-day.ngs-calendar-day-hidden{visibility:hidden;pointer-events:none}:host button.ngs-calendar-day.ngs-calendar-day-selected{--ngs-button-bg: var(--ngs-calendar-day-selected-bg);color:var(--ngs-calendar-day-selected-color)}:host button.ngs-calendar-day.ngs-calendar-day-today:not(.ngs-calendar-day-selected){outline:var(--ngs-calendar-day-today-outline);outline-offset:-1px}:host button.ngs-calendar-day ::ng-deep>.content{display:flex;width:100%;max-width:100%;min-width:0;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:inherit;gap:inherit;line-height:normal}:host .ngs-calendar-day-number{display:inline-flex;align-items:center;justify-content:center;width:calc(var(--spacing, .25rem) * 6);height:calc(var(--spacing, .25rem) * 6);line-height:1}:host .ngs-calendar-event-markers{display:inline-flex;max-width:100%;min-height:calc(var(--spacing, .25rem) * 1.5);align-items:center;justify-content:center;gap:2px}:host .ngs-calendar-event-marker{width:calc(var(--spacing, .25rem) * 1.5);height:calc(var(--spacing, .25rem) * 1.5);flex:none;border-radius:999px;background:var(--ngs-calendar-event-primary)}:host .ngs-calendar-event-marker.ngs-calendar-event-success{background:var(--ngs-calendar-event-success)}:host .ngs-calendar-event-marker.ngs-calendar-event-warning{background:var(--ngs-calendar-event-warning)}:host .ngs-calendar-event-marker.ngs-calendar-event-danger{background:var(--ngs-calendar-event-danger)}:host .ngs-calendar-event-marker.ngs-calendar-event-info{background:var(--ngs-calendar-event-info)}:host .ngs-calendar-event-marker.ngs-calendar-event-neutral{background:var(--ngs-calendar-event-neutral)}:host .ngs-calendar-event-marker.ngs-calendar-event-green{background:var(--ngs-calendar-event-green)}:host .ngs-calendar-event-marker.ngs-calendar-event-rose{background:var(--ngs-calendar-event-rose)}:host .ngs-calendar-event-marker.ngs-calendar-event-blue{background:var(--ngs-calendar-event-blue)}:host .ngs-calendar-event-list{display:flex;width:100%;min-width:0;flex-direction:column;gap:2px}:host .ngs-calendar-event-title{display:block;box-sizing:border-box;overflow:hidden;width:100%;max-width:100%;min-width:0;padding-inline:calc(var(--spacing, .25rem) * 1);border-radius:var(--ngs-radius-sm);background:var(--ngs-calendar-event-primary);color:currentColor;font-size:var(--ngs-font-size-xs);font-weight:400;line-height:1.35;text-align:left;text-overflow:ellipsis;white-space:nowrap}@supports (color: color-mix(in lab,red,red)){:host .ngs-calendar-event-title{background:color-mix(in srgb,var(--ngs-calendar-event-primary),transparent 88%)}}:host .ngs-calendar-day-selected .ngs-calendar-event-marker{background:currentColor}:host .ngs-calendar-day-selected .ngs-calendar-event-title{background:currentColor}@supports (color: color-mix(in lab,red,red)){:host .ngs-calendar-day-selected .ngs-calendar-event-title{background:color-mix(in srgb,currentColor,transparent 84%)}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
|
|
231
|
+
}], ctorParameters: () => [], propDecorators: { startAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAt", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], showAdjacentDays: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAdjacentDays", required: false }] }], showTodayButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTodayButton", required: false }] }], showEventTitles: [{ type: i0.Input, args: [{ isSignal: true, alias: "showEventTitles", required: false }] }], selectedChange: [{ type: i0.Output, args: ["selectedChange"] }], monthChange: [{ type: i0.Output, args: ["monthChange"] }], eventSelected: [{ type: i0.Output, args: ["eventSelected"] }] } });
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Generated bundle index. Do not edit.
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
export { Calendar };
|
|
238
|
+
//# sourceMappingURL=ngstarter-ui-components-calendar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngstarter-ui-components-calendar.mjs","sources":["../../../projects/components/calendar/src/calendar/calendar.ts","../../../projects/components/calendar/src/calendar/calendar.html","../../../projects/components/calendar/ngstarter-ui-components-calendar.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\nimport { Button } from '@ngstarter-ui/components/button';\nimport { Icon } from '@ngstarter-ui/components/icon';\n\nexport type CalendarDateInput = Date | string | number;\n\nexport type CalendarEventColor =\n | 'primary'\n | 'success'\n | 'warning'\n | 'danger'\n | 'info'\n | 'neutral'\n | 'green'\n | 'rose'\n | 'blue';\n\nexport interface CalendarEvent {\n readonly id?: string | number;\n readonly date: CalendarDateInput;\n readonly title?: string;\n readonly color?: CalendarEventColor;\n}\n\ninterface CalendarCell {\n readonly date: Date;\n readonly key: string;\n readonly label: string;\n readonly ariaLabel: string;\n readonly inCurrentMonth: boolean;\n readonly visible: boolean;\n readonly today: boolean;\n readonly selected: boolean;\n readonly disabled: boolean;\n readonly events: readonly CalendarEvent[];\n readonly markers: readonly CalendarEventColor[];\n}\n\n@Component({\n selector: 'ngs-calendar',\n exportAs: 'ngsCalendar',\n standalone: true,\n imports: [Button, Icon],\n templateUrl: './calendar.html',\n styleUrl: './calendar.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'ngs-calendar',\n },\n})\nexport class Calendar {\n readonly startAt = input<CalendarDateInput | null>(null);\n readonly selected = input<CalendarDateInput | null>(null);\n readonly minDate = input<CalendarDateInput | null>(null);\n readonly maxDate = input<CalendarDateInput | null>(null);\n readonly events = input<readonly CalendarEvent[]>([]);\n readonly locale = input<string | undefined>(undefined);\n readonly firstDayOfWeek = input(0, { transform: numberAttribute });\n readonly showAdjacentDays = input(true, { transform: booleanAttribute });\n readonly showTodayButton = input(true, { transform: booleanAttribute });\n readonly showEventTitles = input(false, { transform: booleanAttribute });\n\n readonly selectedChange = output<Date>();\n readonly monthChange = output<Date>();\n readonly eventSelected = output<CalendarEvent>();\n\n protected readonly activeMonth = signal(this.getInitialActiveMonth());\n protected readonly selectedDate = signal<Date | null>(this.normalizeDateInput(this.selected()));\n\n protected readonly normalizedMinDate = computed(() => this.normalizeDateInput(this.minDate()));\n protected readonly normalizedMaxDate = computed(() => this.normalizeDateInput(this.maxDate()));\n\n protected readonly periodLabel = computed(() =>\n new Intl.DateTimeFormat(this.locale(), {\n month: 'long',\n year: 'numeric',\n }).format(this.activeMonth()),\n );\n\n protected readonly weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(this.locale(), { weekday: 'short' });\n const labels: string[] = [];\n const weekStart = this.normalizedFirstDayOfWeek();\n\n for (let index = 0; index < 7; index++) {\n const date = new Date(2024, 0, 7 + weekStart + index);\n labels.push(formatter.format(date));\n }\n\n return labels;\n });\n\n protected readonly calendarCells = computed<readonly CalendarCell[]>(() => {\n const activeMonth = this.activeMonth();\n const selectedDate = this.selectedDate();\n const minDate = this.normalizedMinDate();\n const maxDate = this.normalizedMaxDate();\n const showAdjacentDays = this.showAdjacentDays();\n const monthStart = this.startOfMonth(activeMonth);\n const weekStart = this.normalizedFirstDayOfWeek();\n const firstDayOffset = (monthStart.getDay() - weekStart + 7) % 7;\n const gridStart = this.addDays(monthStart, -firstDayOffset);\n const today = this.startOfDay(new Date());\n const eventMap = this.eventsByDate();\n const cells: CalendarCell[] = [];\n\n for (let index = 0; index < 42; index++) {\n const date = this.addDays(gridStart, index);\n const inCurrentMonth = this.sameMonth(date, activeMonth);\n const events = eventMap.get(this.dateKey(date)) ?? [];\n const visible = inCurrentMonth || showAdjacentDays;\n\n cells.push({\n date,\n key: this.dateKey(date),\n label: visible ? String(date.getDate()) : '',\n ariaLabel: this.formatFullDate(date),\n inCurrentMonth,\n visible,\n today: this.sameDate(date, today),\n selected: !!selectedDate && this.sameDate(date, selectedDate),\n disabled: this.isDisabled(date, minDate, maxDate) || !visible,\n events,\n markers: this.uniqueEventColors(events),\n });\n }\n\n return cells;\n });\n\n constructor() {\n effect(() => {\n const selected = this.normalizeDateInput(this.selected());\n\n this.selectedDate.set(selected);\n\n if (selected) {\n this.activeMonth.set(this.startOfMonth(selected));\n }\n });\n\n effect(() => {\n const startAt = this.normalizeDateInput(this.startAt());\n\n if (startAt) {\n this.activeMonth.set(this.startOfMonth(startAt));\n }\n });\n }\n\n protected previousMonth(): void {\n this.setActiveMonth(this.addMonths(this.activeMonth(), -1));\n }\n\n protected nextMonth(): void {\n this.setActiveMonth(this.addMonths(this.activeMonth(), 1));\n }\n\n protected selectToday(): void {\n const today = this.startOfDay(new Date());\n\n this.setActiveMonth(today);\n\n if (!this.isDisabled(today, this.normalizedMinDate(), this.normalizedMaxDate())) {\n this.selectDate(today);\n }\n }\n\n protected selectCell(cell: CalendarCell): void {\n if (cell.disabled) {\n return;\n }\n\n if (!cell.inCurrentMonth) {\n this.setActiveMonth(cell.date);\n }\n\n this.selectDate(cell.date);\n }\n\n protected selectEvent(event: CalendarEvent, domEvent: MouseEvent): void {\n domEvent.stopPropagation();\n this.eventSelected.emit(event);\n }\n\n protected markerClass(color: CalendarEventColor): string {\n return `ngs-calendar-event-${color}`;\n }\n\n private selectDate(date: Date): void {\n const value = this.startOfDay(date);\n\n this.selectedDate.set(value);\n this.selectedChange.emit(this.cloneDate(value));\n }\n\n private setActiveMonth(date: Date): void {\n const month = this.startOfMonth(date);\n\n this.activeMonth.set(month);\n this.monthChange.emit(this.cloneDate(month));\n }\n\n private getInitialActiveMonth(): Date {\n return this.startOfMonth(\n this.normalizeDateInput(this.selected()) ??\n this.normalizeDateInput(this.startAt()) ??\n new Date(),\n );\n }\n\n private eventsByDate(): Map<string, CalendarEvent[]> {\n const map = new Map<string, CalendarEvent[]>();\n\n for (const event of this.events()) {\n const date = this.normalizeDateInput(event.date);\n\n if (!date) {\n continue;\n }\n\n const key = this.dateKey(date);\n const events = map.get(key) ?? [];\n events.push(event);\n map.set(key, events);\n }\n\n return map;\n }\n\n private uniqueEventColors(events: readonly CalendarEvent[]): readonly CalendarEventColor[] {\n const colors = new Set<CalendarEventColor>();\n\n for (const event of events) {\n colors.add(event.color ?? 'primary');\n }\n\n return [...colors].slice(0, 3);\n }\n\n private normalizedFirstDayOfWeek(): number {\n const value = this.firstDayOfWeek();\n\n if (!Number.isFinite(value)) {\n return 0;\n }\n\n return ((Math.trunc(value) % 7) + 7) % 7;\n }\n\n private normalizeDateInput(value: CalendarDateInput | null | undefined): Date | null {\n if (value === null || value === undefined || value === '') {\n return null;\n }\n\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? null : this.startOfDay(value);\n }\n\n if (typeof value === 'string') {\n const dateOnly = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n\n if (dateOnly) {\n const year = Number(dateOnly[1]);\n const month = Number(dateOnly[2]) - 1;\n const day = Number(dateOnly[3]);\n const date = new Date(year, month, day);\n\n return Number.isNaN(date.getTime()) ? null : this.startOfDay(date);\n }\n }\n\n const date = new Date(value);\n\n return Number.isNaN(date.getTime()) ? null : this.startOfDay(date);\n }\n\n private isDisabled(date: Date, minDate: Date | null, maxDate: Date | null): boolean {\n return (\n (!!minDate && this.compareDate(date, minDate) < 0) ||\n (!!maxDate && this.compareDate(date, maxDate) > 0)\n );\n }\n\n private formatFullDate(date: Date): string {\n return new Intl.DateTimeFormat(this.locale(), {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n }).format(date);\n }\n\n private addMonths(date: Date, months: number): Date {\n return new Date(date.getFullYear(), date.getMonth() + months, 1);\n }\n\n private addDays(date: Date, days: number): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n }\n\n private startOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n }\n\n private startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n }\n\n private cloneDate(date: Date): Date {\n return new Date(date.getTime());\n }\n\n private sameMonth(first: Date, second: Date): boolean {\n return first.getFullYear() === second.getFullYear() && first.getMonth() === second.getMonth();\n }\n\n private sameDate(first: Date, second: Date): boolean {\n return this.compareDate(first, second) === 0;\n }\n\n private compareDate(first: Date, second: Date): number {\n return (\n first.getFullYear() - second.getFullYear() ||\n first.getMonth() - second.getMonth() ||\n first.getDate() - second.getDate()\n );\n }\n\n private dateKey(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n return `${year}-${month}-${day}`;\n }\n}\n","<div class=\"ngs-calendar-header\">\n <button\n ngsIconButton\n type=\"button\"\n class=\"ngs-calendar-previous-button\"\n aria-label=\"Previous month\"\n (click)=\"previousMonth()\"\n >\n <ngs-icon name=\"fluent:chevron-left-24-regular\" />\n </button>\n\n <div class=\"ngs-calendar-period\" aria-live=\"polite\">{{ periodLabel() }}</div>\n\n <div class=\"ngs-calendar-actions\">\n @if (showTodayButton()) {\n <button ngsButton type=\"button\" class=\"ngs-calendar-today-button\" (click)=\"selectToday()\">\n Today\n </button>\n }\n\n <button\n ngsIconButton\n type=\"button\"\n class=\"ngs-calendar-next-button\"\n aria-label=\"Next month\"\n (click)=\"nextMonth()\"\n >\n <ngs-icon name=\"fluent:chevron-right-24-regular\" />\n </button>\n </div>\n</div>\n\n<div class=\"ngs-calendar-weekdays\" role=\"row\">\n @for (weekday of weekdayLabels(); track weekday) {\n <div class=\"ngs-calendar-weekday\" role=\"columnheader\">{{ weekday }}</div>\n }\n</div>\n\n<div class=\"ngs-calendar-grid\" role=\"grid\" [attr.aria-label]=\"periodLabel()\">\n @for (cell of calendarCells(); track cell.key) {\n <button\n ngsButton\n type=\"button\"\n class=\"ngs-calendar-day\"\n [class.ngs-calendar-day-hidden]=\"!cell.visible\"\n [class.ngs-calendar-day-muted]=\"!cell.inCurrentMonth\"\n [class.ngs-calendar-day-today]=\"cell.today\"\n [class.ngs-calendar-day-selected]=\"cell.selected\"\n [class.ngs-calendar-day-has-events]=\"cell.events.length > 0\"\n [disabled]=\"cell.disabled\"\n [attr.aria-label]=\"cell.ariaLabel\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.data-date]=\"cell.key\"\n role=\"gridcell\"\n (click)=\"selectCell(cell)\"\n >\n <span class=\"ngs-calendar-day-number\">{{ cell.label }}</span>\n\n @if (cell.markers.length > 0) {\n <span class=\"ngs-calendar-event-markers\" aria-hidden=\"true\">\n @for (marker of cell.markers; track marker) {\n <span class=\"ngs-calendar-event-marker {{ markerClass(marker) }}\"></span>\n }\n </span>\n }\n\n @if (showEventTitles() && cell.events.length > 0) {\n <span class=\"ngs-calendar-event-list\">\n @for (event of cell.events.slice(0, 2); track event.id ?? event.title ?? $index) {\n <span class=\"ngs-calendar-event-title\" (click)=\"selectEvent(event, $event)\">\n {{ event.title }}\n </span>\n }\n </span>\n }\n </button>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ngstarter-ui/components",
|
|
3
3
|
"description": "NgStarter - AI-friendly Enterprise Angular UI Components and Admin Panel",
|
|
4
|
-
"version": "21.0.
|
|
4
|
+
"version": "21.0.10",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/elementarlabsdev/ngstarter.git"
|
|
@@ -110,6 +110,10 @@
|
|
|
110
110
|
"types": "./types/ngstarter-ui-components-button-toggle.d.ts",
|
|
111
111
|
"default": "./fesm2022/ngstarter-ui-components-button-toggle.mjs"
|
|
112
112
|
},
|
|
113
|
+
"./calendar": {
|
|
114
|
+
"types": "./types/ngstarter-ui-components-calendar.d.ts",
|
|
115
|
+
"default": "./fesm2022/ngstarter-ui-components-calendar.mjs"
|
|
116
|
+
},
|
|
113
117
|
"./card": {
|
|
114
118
|
"types": "./types/ngstarter-ui-components-card.d.ts",
|
|
115
119
|
"default": "./fesm2022/ngstarter-ui-components-card.mjs"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
type CalendarDateInput = Date | string | number;
|
|
4
|
+
type CalendarEventColor = 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'neutral' | 'green' | 'rose' | 'blue';
|
|
5
|
+
interface CalendarEvent {
|
|
6
|
+
readonly id?: string | number;
|
|
7
|
+
readonly date: CalendarDateInput;
|
|
8
|
+
readonly title?: string;
|
|
9
|
+
readonly color?: CalendarEventColor;
|
|
10
|
+
}
|
|
11
|
+
interface CalendarCell {
|
|
12
|
+
readonly date: Date;
|
|
13
|
+
readonly key: string;
|
|
14
|
+
readonly label: string;
|
|
15
|
+
readonly ariaLabel: string;
|
|
16
|
+
readonly inCurrentMonth: boolean;
|
|
17
|
+
readonly visible: boolean;
|
|
18
|
+
readonly today: boolean;
|
|
19
|
+
readonly selected: boolean;
|
|
20
|
+
readonly disabled: boolean;
|
|
21
|
+
readonly events: readonly CalendarEvent[];
|
|
22
|
+
readonly markers: readonly CalendarEventColor[];
|
|
23
|
+
}
|
|
24
|
+
declare class Calendar {
|
|
25
|
+
readonly startAt: _angular_core.InputSignal<CalendarDateInput | null>;
|
|
26
|
+
readonly selected: _angular_core.InputSignal<CalendarDateInput | null>;
|
|
27
|
+
readonly minDate: _angular_core.InputSignal<CalendarDateInput | null>;
|
|
28
|
+
readonly maxDate: _angular_core.InputSignal<CalendarDateInput | null>;
|
|
29
|
+
readonly events: _angular_core.InputSignal<readonly CalendarEvent[]>;
|
|
30
|
+
readonly locale: _angular_core.InputSignal<string | undefined>;
|
|
31
|
+
readonly firstDayOfWeek: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
32
|
+
readonly showAdjacentDays: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
33
|
+
readonly showTodayButton: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
34
|
+
readonly showEventTitles: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
35
|
+
readonly selectedChange: _angular_core.OutputEmitterRef<Date>;
|
|
36
|
+
readonly monthChange: _angular_core.OutputEmitterRef<Date>;
|
|
37
|
+
readonly eventSelected: _angular_core.OutputEmitterRef<CalendarEvent>;
|
|
38
|
+
protected readonly activeMonth: _angular_core.WritableSignal<Date>;
|
|
39
|
+
protected readonly selectedDate: _angular_core.WritableSignal<Date | null>;
|
|
40
|
+
protected readonly normalizedMinDate: _angular_core.Signal<Date | null>;
|
|
41
|
+
protected readonly normalizedMaxDate: _angular_core.Signal<Date | null>;
|
|
42
|
+
protected readonly periodLabel: _angular_core.Signal<string>;
|
|
43
|
+
protected readonly weekdayLabels: _angular_core.Signal<string[]>;
|
|
44
|
+
protected readonly calendarCells: _angular_core.Signal<readonly CalendarCell[]>;
|
|
45
|
+
constructor();
|
|
46
|
+
protected previousMonth(): void;
|
|
47
|
+
protected nextMonth(): void;
|
|
48
|
+
protected selectToday(): void;
|
|
49
|
+
protected selectCell(cell: CalendarCell): void;
|
|
50
|
+
protected selectEvent(event: CalendarEvent, domEvent: MouseEvent): void;
|
|
51
|
+
protected markerClass(color: CalendarEventColor): string;
|
|
52
|
+
private selectDate;
|
|
53
|
+
private setActiveMonth;
|
|
54
|
+
private getInitialActiveMonth;
|
|
55
|
+
private eventsByDate;
|
|
56
|
+
private uniqueEventColors;
|
|
57
|
+
private normalizedFirstDayOfWeek;
|
|
58
|
+
private normalizeDateInput;
|
|
59
|
+
private isDisabled;
|
|
60
|
+
private formatFullDate;
|
|
61
|
+
private addMonths;
|
|
62
|
+
private addDays;
|
|
63
|
+
private startOfMonth;
|
|
64
|
+
private startOfDay;
|
|
65
|
+
private cloneDate;
|
|
66
|
+
private sameMonth;
|
|
67
|
+
private sameDate;
|
|
68
|
+
private compareDate;
|
|
69
|
+
private dateKey;
|
|
70
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Calendar, never>;
|
|
71
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Calendar, "ngs-calendar", ["ngsCalendar"], { "startAt": { "alias": "startAt"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "events": { "alias": "events"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "firstDayOfWeek": { "alias": "firstDayOfWeek"; "required": false; "isSignal": true; }; "showAdjacentDays": { "alias": "showAdjacentDays"; "required": false; "isSignal": true; }; "showTodayButton": { "alias": "showTodayButton"; "required": false; "isSignal": true; }; "showEventTitles": { "alias": "showEventTitles"; "required": false; "isSignal": true; }; }, { "selectedChange": "selectedChange"; "monthChange": "monthChange"; "eventSelected": "eventSelected"; }, never, never, true, never>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { Calendar };
|
|
75
|
+
export type { CalendarDateInput, CalendarEvent, CalendarEventColor };
|