shdr-calendar 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,12 @@
1
- import { Component, signal, computed, inject } from '@angular/core';
1
+ import { Component, signal, computed, inject, input } from '@angular/core';
2
2
  import { NgFor } from '@angular/common';
3
3
  import { CalendarService } from './calendar.service';
4
4
  import * as i0 from "@angular/core";
5
5
  export class CalendarComponent {
6
6
  constructor() {
7
7
  this.calendarService = inject(CalendarService);
8
+ /** 可选。与接口 data.calendarList 一致,用于按日期显示状态(如 AVAILABLE / PURCHASED) */
9
+ this.calendarStates = input([]);
8
10
  this.currentDate = signal(new Date());
9
11
  this.selectedDate = signal(null);
10
12
  this.weekDays = this.calendarService.getWeekDayLabels();
@@ -15,14 +17,27 @@ export class CalendarComponent {
15
17
  this.days = computed(() => {
16
18
  const d = this.currentDate();
17
19
  const selected = this.selectedDate();
20
+ const states = this.calendarStates();
21
+ const stateMap = new Map(states.map((s) => [s.date, s]));
18
22
  const days = this.calendarService.getDaysInMonth(d.getFullYear(), d.getMonth());
19
- return days.map((day) => ({
20
- ...day,
21
- isSelected: selected !== null &&
22
- this.calendarService.isSameDay(day.date, selected),
23
- }));
23
+ return days.map((day) => {
24
+ const key = this.formatDateKey(day.date);
25
+ const state = stateMap.get(key);
26
+ return {
27
+ ...day,
28
+ isSelected: selected !== null &&
29
+ this.calendarService.isSameDay(day.date, selected),
30
+ status: state?.status,
31
+ };
32
+ });
24
33
  });
25
34
  }
35
+ formatDateKey(date) {
36
+ const y = date.getFullYear();
37
+ const m = String(date.getMonth() + 1).padStart(2, '0');
38
+ const day = String(date.getDate()).padStart(2, '0');
39
+ return `${y}-${m}-${day}`;
40
+ }
26
41
  prevMonth() {
27
42
  const d = this.currentDate();
28
43
  this.currentDate.set(new Date(d.getFullYear(), d.getMonth() - 1));
@@ -40,10 +55,10 @@ export class CalendarComponent {
40
55
  this.selectedDate.set(today);
41
56
  }
42
57
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
43
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CalendarComponent, isStandalone: true, selector: "shdr-calendar", ngImport: i0, template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}\n"] }); }
58
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CalendarComponent, isStandalone: true, selector: "shdr-calendar", inputs: { calendarStates: { classPropertyName: "calendarStates", publicName: "calendarStates", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.status-available]=\"day.status === 'AVAILABLE'\"\n [class.status-purchased]=\"day.status === 'PURCHASED'\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{position:relative;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}.day-cell.status-available{--cal-dot: #22c55e}.day-cell.status-available:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}.day-cell.status-purchased{--cal-dot: #94a3b8}.day-cell.status-purchased:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}\n"] }); }
44
59
  }
45
60
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarComponent, decorators: [{
46
61
  type: Component,
47
- args: [{ selector: 'shdr-calendar', standalone: true, imports: [NgFor], template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}\n"] }]
62
+ args: [{ selector: 'shdr-calendar', standalone: true, imports: [NgFor], template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.status-available]=\"day.status === 'AVAILABLE'\"\n [class.status-purchased]=\"day.status === 'PURCHASED'\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{position:relative;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}.day-cell.status-available{--cal-dot: #22c55e}.day-cell.status-available:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}.day-cell.status-purchased{--cal-dot: #94a3b8}.day-cell.status-purchased:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}\n"] }]
48
63
  }] });
49
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvc2hkci1jYWxlbmRhci9zcmMvbGliL2NhbGVuZGFyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL2xpYi9jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZUFBZSxFQUFvQixNQUFNLG9CQUFvQixDQUFDOztBQVN2RSxNQUFNLE9BQU8saUJBQWlCO0lBUDlCO1FBUVUsb0JBQWUsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFbEQsZ0JBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLGlCQUFZLEdBQUcsTUFBTSxDQUFjLElBQUksQ0FBQyxDQUFDO1FBRXpDLGFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFbkQsbUJBQWMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQzdCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM3QixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO1FBRUgsU0FBSSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FDOUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUNmLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FDYixDQUFDO1lBQ0YsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN4QixHQUFHLEdBQUc7Z0JBQ04sVUFBVSxFQUNSLFFBQVEsS0FBSyxJQUFJO29CQUNqQixJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQzthQUNyRCxDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0tBcUJKO0lBbkJDLFNBQVM7UUFDUCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRCxTQUFTO1FBQ1AsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQWdCO1FBQ3hCLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsU0FBUztRQUNQLE1BQU0sS0FBSyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQzsrR0E5Q1UsaUJBQWlCO21HQUFqQixpQkFBaUIseUVDWDlCLG9oQ0FrQ0E7OzRGRHZCYSxpQkFBaUI7a0JBUDdCLFNBQVM7K0JBQ0UsZUFBZSxjQUNiLElBQUksV0FDUCxDQUFDLEtBQUssQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgc2lnbmFsLCBjb21wdXRlZCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ0ZvciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDYWxlbmRhclNlcnZpY2UsIHR5cGUgQ2FsZW5kYXJEYXkgfSBmcm9tICcuL2NhbGVuZGFyLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzaGRyLWNhbGVuZGFyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW05nRm9yXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJDb21wb25lbnQge1xuICBwcml2YXRlIGNhbGVuZGFyU2VydmljZSA9IGluamVjdChDYWxlbmRhclNlcnZpY2UpO1xuXG4gIGN1cnJlbnREYXRlID0gc2lnbmFsKG5ldyBEYXRlKCkpO1xuICBzZWxlY3RlZERhdGUgPSBzaWduYWw8RGF0ZSB8IG51bGw+KG51bGwpO1xuXG4gIHdlZWtEYXlzID0gdGhpcy5jYWxlbmRhclNlcnZpY2UuZ2V0V2Vla0RheUxhYmVscygpO1xuXG4gIG1vbnRoWWVhckxhYmVsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmN1cnJlbnREYXRlKCk7XG4gICAgcmV0dXJuIHRoaXMuY2FsZW5kYXJTZXJ2aWNlLmdldE1vbnRoWWVhckxhYmVsKGQuZ2V0RnVsbFllYXIoKSwgZC5nZXRNb250aCgpKTtcbiAgfSk7XG5cbiAgZGF5cyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5jdXJyZW50RGF0ZSgpO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZERhdGUoKTtcbiAgICBjb25zdCBkYXlzID0gdGhpcy5jYWxlbmRhclNlcnZpY2UuZ2V0RGF5c0luTW9udGgoXG4gICAgICBkLmdldEZ1bGxZZWFyKCksXG4gICAgICBkLmdldE1vbnRoKClcbiAgICApO1xuICAgIHJldHVybiBkYXlzLm1hcCgoZGF5KSA9PiAoe1xuICAgICAgLi4uZGF5LFxuICAgICAgaXNTZWxlY3RlZDpcbiAgICAgICAgc2VsZWN0ZWQgIT09IG51bGwgJiZcbiAgICAgICAgdGhpcy5jYWxlbmRhclNlcnZpY2UuaXNTYW1lRGF5KGRheS5kYXRlLCBzZWxlY3RlZCksXG4gICAgfSkpO1xuICB9KTtcblxuICBwcmV2TW9udGgoKTogdm9pZCB7XG4gICAgY29uc3QgZCA9IHRoaXMuY3VycmVudERhdGUoKTtcbiAgICB0aGlzLmN1cnJlbnREYXRlLnNldChuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCksIGQuZ2V0TW9udGgoKSAtIDEpKTtcbiAgfVxuXG4gIG5leHRNb250aCgpOiB2b2lkIHtcbiAgICBjb25zdCBkID0gdGhpcy5jdXJyZW50RGF0ZSgpO1xuICAgIHRoaXMuY3VycmVudERhdGUuc2V0KG5ldyBEYXRlKGQuZ2V0RnVsbFllYXIoKSwgZC5nZXRNb250aCgpICsgMSkpO1xuICB9XG5cbiAgc2VsZWN0RGF5KGRheTogQ2FsZW5kYXJEYXkpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZS5zZXQoZGF5LmRhdGUpO1xuICB9XG5cbiAgZ29Ub1RvZGF5KCk6IHZvaWQge1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICB0aGlzLmN1cnJlbnREYXRlLnNldCh0b2RheSk7XG4gICAgdGhpcy5zZWxlY3RlZERhdGUuc2V0KHRvZGF5KTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNhbGVuZGFyXCI+XG4gIDxoZWFkZXIgY2xhc3M9XCJjYWxlbmRhci1oZWFkZXJcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm5hdi1idG5cIiAoY2xpY2spPVwicHJldk1vbnRoKClcIiBhcmlhLWxhYmVsPVwi5LiK5LiA5pyIXCI+XG4gICAgICDigLlcbiAgICA8L2J1dHRvbj5cbiAgICA8aDIgY2xhc3M9XCJtb250aC15ZWFyXCI+e3sgbW9udGhZZWFyTGFiZWwoKSB9fTwvaDI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJuYXYtYnRuXCIgKGNsaWNrKT1cIm5leHRNb250aCgpXCIgYXJpYS1sYWJlbD1cIuS4i+S4gOaciFwiPlxuICAgICAg4oC6XG4gICAgPC9idXR0b24+XG4gIDwvaGVhZGVyPlxuXG4gIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidG9kYXktYnRuXCIgKGNsaWNrKT1cImdvVG9Ub2RheSgpXCI+5LuK5aSpPC9idXR0b24+XG5cbiAgPGRpdiBjbGFzcz1cIndlZWtkYXlzXCI+XG4gICAgQGZvciAobGFiZWwgb2Ygd2Vla0RheXM7IHRyYWNrIGxhYmVsKSB7XG4gICAgICA8c3BhbiBjbGFzcz1cIndlZWtkYXlcIj57eyBsYWJlbCB9fTwvc3Bhbj5cbiAgICB9XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJkYXlzLWdyaWRcIj5cbiAgICBAZm9yIChkYXkgb2YgZGF5cygpOyB0cmFjayBkYXkuZGF0ZS5nZXRUaW1lKCkpIHtcbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiZGF5LWNlbGxcIlxuICAgICAgICBbY2xhc3Mub3RoZXItbW9udGhdPVwiIWRheS5pc0N1cnJlbnRNb250aFwiXG4gICAgICAgIFtjbGFzcy50b2RheV09XCJkYXkuaXNUb2RheVwiXG4gICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkYXkuaXNTZWxlY3RlZFwiXG4gICAgICAgIChjbGljayk9XCJzZWxlY3REYXkoZGF5KVwiXG4gICAgICA+XG4gICAgICAgIHt7IGRheS5kYXkgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIH1cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvc2hkci1jYWxlbmRhci9zcmMvbGliL2NhbGVuZGFyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL2xpYi9jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEMsT0FBTyxFQUFFLGVBQWUsRUFBMkMsTUFBTSxvQkFBb0IsQ0FBQzs7QUFTOUYsTUFBTSxPQUFPLGlCQUFpQjtJQVA5QjtRQVFVLG9CQUFlLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRWxELHFFQUFxRTtRQUNyRSxtQkFBYyxHQUFHLEtBQUssQ0FBcUIsRUFBRSxDQUFDLENBQUM7UUFFL0MsZ0JBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLGlCQUFZLEdBQUcsTUFBTSxDQUFjLElBQUksQ0FBQyxDQUFDO1FBRXpDLGFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFbkQsbUJBQWMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQzdCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM3QixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO1FBRUgsU0FBSSxHQUFHLFFBQVEsQ0FBQyxH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LFNBQVM7K0JBQ0UsZUFBZSxjQUNiLElBQUksV0FDUCxDQUFDLEtBQUssQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgc2lnbmFsLCBjb21wdXRlZCwgaW5qZWN0LCBpbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmdGb3IgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ2FsZW5kYXJTZXJ2aWNlLCB0eXBlIENhbGVuZGFyRGF5LCB0eXBlIENhbGVuZGFyRGF5U3RhdGUgfSBmcm9tICcuL2NhbGVuZGFyLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzaGRyLWNhbGVuZGFyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW05nRm9yXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJDb21wb25lbnQge1xuICBwcml2YXRlIGNhbGVuZGFyU2VydmljZSA9IGluamVjdChDYWxlbmRhclNlcnZpY2UpO1xuXG4gIC8qKiDlj6/pgInjgILkuI7mjqXlj6MgZGF0YS5jYWxlbmRhckxpc3Qg5LiA6Ie077yM55So5LqO5oyJ5pel5pyf5pi+56S654q25oCB77yI5aaCIEFWQUlMQUJMRSAvIFBVUkNIQVNFRO+8iSAqL1xuICBjYWxlbmRhclN0YXRlcyA9IGlucHV0PENhbGVuZGFyRGF5U3RhdGVbXT4oW10pO1xuXG4gIGN1cnJlbnREYXRlID0gc2lnbmFsKG5ldyBEYXRlKCkpO1xuICBzZWxlY3RlZERhdGUgPSBzaWduYWw8RGF0ZSB8IG51bGw+KG51bGwpO1xuXG4gIHdlZWtEYXlzID0gdGhpcy5jYWxlbmRhclNlcnZpY2UuZ2V0V2Vla0RheUxhYmVscygpO1xuXG4gIG1vbnRoWWVhckxhYmVsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmN1cnJlbnREYXRlKCk7XG4gICAgcmV0dXJuIHRoaXMuY2FsZW5kYXJTZXJ2aWNlLmdldE1vbnRoWWVhckxhYmVsKGQuZ2V0RnVsbFllYXIoKSwgZC5nZXRNb250aCgpKTtcbiAgfSk7XG5cbiAgZGF5cyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5jdXJyZW50RGF0ZSgpO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZERhdGUoKTtcbiAgICBjb25zdCBzdGF0ZXMgPSB0aGlzLmNhbGVuZGFyU3RhdGVzKCk7XG4gICAgY29uc3Qgc3RhdGVNYXAgPSBuZXcgTWFwKHN0YXRlcy5tYXAoKHMpID0+IFtzLmRhdGUsIHNdKSk7XG4gICAgY29uc3QgZGF5cyA9IHRoaXMuY2FsZW5kYXJTZXJ2aWNlLmdldERheXNJbk1vbnRoKFxuICAgICAgZC5nZXRGdWxsWWVhcigpLFxuICAgICAgZC5nZXRNb250aCgpXG4gICAgKTtcbiAgICByZXR1cm4gZGF5cy5tYXAoKGRheSkgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gdGhpcy5mb3JtYXREYXRlS2V5KGRheS5kYXRlKTtcbiAgICAgIGNvbnN0IHN0YXRlID0gc3RhdGVNYXAuZ2V0KGtleSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5kYXksXG4gICAgICAgIGlzU2VsZWN0ZWQ6XG4gICAgICAgICAgc2VsZWN0ZWQgIT09IG51bGwgJiZcbiAgICAgICAgICB0aGlzLmNhbGVuZGFyU2VydmljZS5pc1NhbWVEYXkoZGF5LmRhdGUsIHNlbGVjdGVkKSxcbiAgICAgICAgc3RhdHVzOiBzdGF0ZT8uc3RhdHVzLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBmb3JtYXREYXRlS2V5KGRhdGU6IERhdGUpOiBzdHJpbmcge1xuICAgIGNvbnN0IHkgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgY29uc3QgbSA9IFN0cmluZyhkYXRlLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IGRheSA9IFN0cmluZyhkYXRlLmdldERhdGUoKSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCR7eX0tJHttfS0ke2RheX1gO1xuICB9XG5cbiAgcHJldk1vbnRoKCk6IHZvaWQge1xuICAgIGNvbnN0IGQgPSB0aGlzLmN1cnJlbnREYXRlKCk7XG4gICAgdGhpcy5jdXJyZW50RGF0ZS5zZXQobmV3IERhdGUoZC5nZXRGdWxsWWVhcigpLCBkLmdldE1vbnRoKCkgLSAxKSk7XG4gIH1cblxuICBuZXh0TW9udGgoKTogdm9pZCB7XG4gICAgY29uc3QgZCA9IHRoaXMuY3VycmVudERhdGUoKTtcbiAgICB0aGlzLmN1cnJlbnREYXRlLnNldChuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCksIGQuZ2V0TW9udGgoKSArIDEpKTtcbiAgfVxuXG4gIHNlbGVjdERheShkYXk6IENhbGVuZGFyRGF5KTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZERhdGUuc2V0KGRheS5kYXRlKTtcbiAgfVxuXG4gIGdvVG9Ub2RheSgpOiB2b2lkIHtcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgdGhpcy5jdXJyZW50RGF0ZS5zZXQodG9kYXkpO1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlLnNldCh0b2RheSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjYWxlbmRhclwiPlxuICA8aGVhZGVyIGNsYXNzPVwiY2FsZW5kYXItaGVhZGVyXCI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJuYXYtYnRuXCIgKGNsaWNrKT1cInByZXZNb250aCgpXCIgYXJpYS1sYWJlbD1cIuS4iuS4gOaciFwiPlxuICAgICAg4oC5XG4gICAgPC9idXR0b24+XG4gICAgPGgyIGNsYXNzPVwibW9udGgteWVhclwiPnt7IG1vbnRoWWVhckxhYmVsKCkgfX08L2gyPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwibmF2LWJ0blwiIChjbGljayk9XCJuZXh0TW9udGgoKVwiIGFyaWEtbGFiZWw9XCLkuIvkuIDmnIhcIj5cbiAgICAgIOKAulxuICAgIDwvYnV0dG9uPlxuICA8L2hlYWRlcj5cblxuICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInRvZGF5LWJ0blwiIChjbGljayk9XCJnb1RvVG9kYXkoKVwiPuS7iuWkqTwvYnV0dG9uPlxuXG4gIDxkaXYgY2xhc3M9XCJ3ZWVrZGF5c1wiPlxuICAgIEBmb3IgKGxhYmVsIG9mIHdlZWtEYXlzOyB0cmFjayBsYWJlbCkge1xuICAgICAgPHNwYW4gY2xhc3M9XCJ3ZWVrZGF5XCI+e3sgbGFiZWwgfX08L3NwYW4+XG4gICAgfVxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiZGF5cy1ncmlkXCI+XG4gICAgQGZvciAoZGF5IG9mIGRheXMoKTsgdHJhY2sgZGF5LmRhdGUuZ2V0VGltZSgpKSB7XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImRheS1jZWxsXCJcbiAgICAgICAgW2NsYXNzLm90aGVyLW1vbnRoXT1cIiFkYXkuaXNDdXJyZW50TW9udGhcIlxuICAgICAgICBbY2xhc3MudG9kYXldPVwiZGF5LmlzVG9kYXlcIlxuICAgICAgICBbY2xhc3Muc2VsZWN0ZWRdPVwiZGF5LmlzU2VsZWN0ZWRcIlxuICAgICAgICBbY2xhc3Muc3RhdHVzLWF2YWlsYWJsZV09XCJkYXkuc3RhdHVzID09PSAnQVZBSUxBQkxFJ1wiXG4gICAgICAgIFtjbGFzcy5zdGF0dXMtcHVyY2hhc2VkXT1cImRheS5zdGF0dXMgPT09ICdQVVJDSEFTRUQnXCJcbiAgICAgICAgKGNsaWNrKT1cInNlbGVjdERheShkYXkpXCJcbiAgICAgID5cbiAgICAgICAge3sgZGF5LmRheSB9fVxuICAgICAgPC9idXR0b24+XG4gICAgfVxuICA8L2Rpdj5cbjwvZGl2PlxuIl19
@@ -69,4 +69,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
69
69
  providedIn: 'root',
70
70
  }]
71
71
  }] });
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL2xpYi9jYWxlbmRhci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBYTNDLE1BQU0sT0FBTyxlQUFlO0lBSDVCO1FBSW1CLGFBQVEsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBb0VqRTtJQWxFQyxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELGNBQWMsQ0FBQyxJQUFZLEVBQUUsS0FBYTtRQUN4QyxNQUFNLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN6QixLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTNCLE1BQU0sSUFBSSxHQUFrQixFQUFFLENBQUM7UUFDL0IsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDO1FBQ3BDLE1BQU0sU0FBUyxHQUFHLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENB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ZTtrQkFIM0IsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJEYXkge1xuICBkYXRlOiBEYXRlO1xuICBkYXk6IG51bWJlcjtcbiAgaXNDdXJyZW50TW9udGg6IGJvb2xlYW47XG4gIGlzVG9kYXk6IGJvb2xlYW47XG4gIGlzU2VsZWN0ZWQ/OiBib29sZWFuO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWVrRGF5cyA9IFsn5pelJywgJ+S4gCcsICfkuownLCAn5LiJJywgJ+WbmycsICfkupQnLCAn5YWtJ107XG5cbiAgZ2V0V2Vla0RheUxhYmVscygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMud2Vla0RheXM7XG4gIH1cblxuICBnZXREYXlzSW5Nb250aCh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBDYWxlbmRhckRheVtdIHtcbiAgICBjb25zdCBmaXJzdCA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAxKTtcbiAgICBjb25zdCBsYXN0ID0gbmV3IERhdGUoeWVhciwgbW9udGggKyAxLCAwKTtcbiAgICBjb25zdCBmaXJzdERheU9mV2VlayA9IGZpcnN0LmdldERheSgpO1xuICAgIGNvbnN0IGRheXNJbk1vbnRoID0gbGFzdC5nZXREYXRlKCk7XG4gICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuICAgIHRvZGF5LnNldEhvdXJzKDAsIDAsIDAsIDApO1xuXG4gICAgY29uc3QgZGF5czogQ2FsZW5kYXJEYXlbXSA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0UGFkZGluZyA9IGZpcnN0RGF5T2ZXZWVrO1xuICAgIGNvbnN0IHByZXZNb250aCA9IG1vbnRoID09PSAwID8gMTEgOiBtb250aCAtIDE7XG4gICAgY29uc3QgcHJldlllYXIgPSBtb250aCA9PT0gMCA/IHllYXIgLSAxIDogeWVhcjtcbiAgICBjb25zdCBwcmV2TW9udGhEYXlzID0gbmV3IERhdGUocHJldlllYXIsIHByZXZNb250aCArIDEsIDApLmdldERhdGUoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhcnRQYWRkaW5nOyBpKyspIHtcbiAgICAgIGNvbnN0IGRheSA9IHByZXZNb250aERheXMgLSBzdGFydFBhZGRpbmcgKyBpICsgMTtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShwcmV2WWVhciwgcHJldk1vbnRoLCBkYXkpO1xuICAgICAgZGF5cy5wdXNoKHtcbiAgICAgICAgZGF0ZSxcbiAgICAgICAgZGF5LFxuICAgICAgICBpc0N1cnJlbnRNb250aDogZmFsc2UsXG4gICAgICAgIGlzVG9kYXk6IHRoaXMuaXNTYW1lRGF5KGRhdGUsIHRvZGF5KSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZvciAobGV0IGQgPSAxOyBkIDw9IGRheXNJbk1vbnRoOyBkKyspIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZCk7XG4gICAgICBkYXlzLnB1c2goe1xuICAgICAgICBkYXRlLFxuICAgICAgICBkYXk6IGQsXG4gICAgICAgIGlzQ3VycmVudE1vbnRoOiB0cnVlLFxuICAgICAgICBpc1RvZGF5OiB0aGlzLmlzU2FtZURheShkYXRlLCB0b2RheSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCByZW1haW5pbmcgPSA0MiAtIGRheXMubGVuZ3RoO1xuICAgIGNvbnN0IG5leHRNb250aCA9IG1vbnRoID09PSAxMSA/IDAgOiBtb250aCArIDE7XG4gICAgY29uc3QgbmV4dFllYXIgPSBtb250aCA9PT0gMTEgPyB5ZWFyICsgMSA6IHllYXI7XG4gICAgZm9yIChsZXQgZCA9IDE7IGQgPD0gcmVtYWluaW5nOyBkKyspIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShuZXh0WWVhciwgbmV4dE1vbnRoLCBkKTtcbiAgICAgIGRheXMucHVzaCh7XG4gICAgICAgIGRhdGUsXG4gICAgICAgIGRheTogZCxcbiAgICAgICAgaXNDdXJyZW50TW9udGg6IGZhbHNlLFxuICAgICAgICBpc1RvZGF5OiB0aGlzLmlzU2FtZURheShkYXRlLCB0b2RheSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF5cztcbiAgfVxuXG4gIGlzU2FtZURheShhOiBEYXRlLCBiOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGEuZ2V0RnVsbFllYXIoKSA9PT0gYi5nZXRGdWxsWWVhcigpICYmXG4gICAgICBhLmdldE1vbnRoKCkgPT09IGIuZ2V0TW9udGgoKSAmJlxuICAgICAgYS5nZXREYXRlKCkgPT09IGIuZ2V0RGF0ZSgpXG4gICAgKTtcbiAgfVxuXG4gIGdldE1vbnRoWWVhckxhYmVsKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3llYXJ95bm0JHttb250aCArIDF95pyIYDtcbiAgfVxufVxuIl19
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL2xpYi9jYWxlbmRhci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBb0IzQyxNQUFNLE9BQU8sZUFBZTtJQUg1QjtRQUltQixhQUFRLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztLQW9FakU7SUFsRUMsZ0JBQWdCO1FBQ2QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxjQUFjLENBQUMsSUFBWSxFQUFFLEtBQWE7UUFDeEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN2QyxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxQyxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLE1BQU0sS0FBSyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDekIsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUUzQixNQUFNLElBQUksR0FBa0IsRUFBRSxDQUFDO1FBQy9CLE1BQU0sWUFBWSxHQUFHLGNBQWMsQ0FBQztRQUNwQyxNQUFNLFNBQVMsR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxD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QWU7a0JBSDNCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENhbGVuZGFyRGF5IHtcbiAgZGF0ZTogRGF0ZTtcbiAgZGF5OiBudW1iZXI7XG4gIGlzQ3VycmVudE1vbnRoOiBib29sZWFuO1xuICBpc1RvZGF5OiBib29sZWFuO1xuICBpc1NlbGVjdGVkPzogYm9vbGVhbjtcbn1cblxuLyoqIOS4juaOpeWPoyBkYXRhLmNhbGVuZGFyTGlzdCDpobnkuIDoh7TvvIznlKjkuo7mjInml6XmnJ/mmL7npLrnirbmgIHvvIjlpoIgQVZBSUxBQkxFIC8gUFVSQ0hBU0VE77yJICovXG5leHBvcnQgaW50ZXJmYWNlIENhbGVuZGFyRGF5U3RhdGUge1xuICBkYXRlOiBzdHJpbmc7IC8vICdZWVlZLU1NLUREJ1xuICBzdGF0dXM6IHN0cmluZzsgLy8gZS5nLiAnQVZBSUxBQkxFJyB8ICdQVVJDSEFTRUQnXG4gIHBsdT86IHN0cmluZztcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIENhbGVuZGFyU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgd2Vla0RheXMgPSBbJ+aXpScsICfkuIAnLCAn5LqMJywgJ+S4iScsICflm5snLCAn5LqUJywgJ+WFrSddO1xuXG4gIGdldFdlZWtEYXlMYWJlbHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLndlZWtEYXlzO1xuICB9XG5cbiAgZ2V0RGF5c0luTW9udGgoeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyKTogQ2FsZW5kYXJEYXlbXSB7XG4gICAgY29uc3QgZmlyc3QgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSk7XG4gICAgY29uc3QgbGFzdCA9IG5ldyBEYXRlKHllYXIsIG1vbnRoICsgMSwgMCk7XG4gICAgY29uc3QgZmlyc3REYXlPZldlZWsgPSBmaXJzdC5nZXREYXkoKTtcbiAgICBjb25zdCBkYXlzSW5Nb250aCA9IGxhc3QuZ2V0RGF0ZSgpO1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICB0b2RheS5zZXRIb3VycygwLCAwLCAwLCAwKTtcblxuICAgIGNvbnN0IGRheXM6IENhbGVuZGFyRGF5W10gPSBbXTtcbiAgICBjb25zdCBzdGFydFBhZGRpbmcgPSBmaXJzdERheU9mV2VlaztcbiAgICBjb25zdCBwcmV2TW9udGggPSBtb250aCA9PT0gMCA/IDExIDogbW9udGggLSAxO1xuICAgIGNvbnN0IHByZXZZZWFyID0gbW9udGggPT09IDAgPyB5ZWFyIC0gMSA6IHllYXI7XG4gICAgY29uc3QgcHJldk1vbnRoRGF5cyA9IG5ldyBEYXRlKHByZXZZZWFyLCBwcmV2TW9udGggKyAxLCAwKS5nZXREYXRlKCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0YXJ0UGFkZGluZzsgaSsrKSB7XG4gICAgICBjb25zdCBkYXkgPSBwcmV2TW9udGhEYXlzIC0gc3RhcnRQYWRkaW5nICsgaSArIDE7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUocHJldlllYXIsIHByZXZNb250aCwgZGF5KTtcbiAgICAgIGRheXMucHVzaCh7XG4gICAgICAgIGRhdGUsXG4gICAgICAgIGRheSxcbiAgICAgICAgaXNDdXJyZW50TW9udGg6IGZhbHNlLFxuICAgICAgICBpc1RvZGF5OiB0aGlzLmlzU2FtZURheShkYXRlLCB0b2RheSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBkID0gMTsgZCA8PSBkYXlzSW5Nb250aDsgZCsrKSB7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoeWVhciwgbW9udGgsIGQpO1xuICAgICAgZGF5cy5wdXNoKHtcbiAgICAgICAgZGF0ZSxcbiAgICAgICAgZGF5OiBkLFxuICAgICAgICBpc0N1cnJlbnRNb250aDogdHJ1ZSxcbiAgICAgICAgaXNUb2RheTogdGhpcy5pc1NhbWVEYXkoZGF0ZSwgdG9kYXkpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVtYWluaW5nID0gNDIgLSBkYXlzLmxlbmd0aDtcbiAgICBjb25zdCBuZXh0TW9udGggPSBtb250aCA9PT0gMTEgPyAwIDogbW9udGggKyAxO1xuICAgIGNvbnN0IG5leHRZZWFyID0gbW9udGggPT09IDExID8geWVhciArIDEgOiB5ZWFyO1xuICAgIGZvciAobGV0IGQgPSAxOyBkIDw9IHJlbWFpbmluZzsgZCsrKSB7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUobmV4dFllYXIsIG5leHRNb250aCwgZCk7XG4gICAgICBkYXlzLnB1c2goe1xuICAgICAgICBkYXRlLFxuICAgICAgICBkYXk6IGQsXG4gICAgICAgIGlzQ3VycmVudE1vbnRoOiBmYWxzZSxcbiAgICAgICAgaXNUb2RheTogdGhpcy5pc1NhbWVEYXkoZGF0ZSwgdG9kYXkpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRheXM7XG4gIH1cblxuICBpc1NhbWVEYXkoYTogRGF0ZSwgYjogRGF0ZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBhLmdldEZ1bGxZZWFyKCkgPT09IGIuZ2V0RnVsbFllYXIoKSAmJlxuICAgICAgYS5nZXRNb250aCgpID09PSBiLmdldE1vbnRoKCkgJiZcbiAgICAgIGEuZ2V0RGF0ZSgpID09PSBiLmdldERhdGUoKVxuICAgICk7XG4gIH1cblxuICBnZXRNb250aFllYXJMYWJlbCh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt5ZWFyfeW5tCR7bW9udGggKyAxfeaciGA7XG4gIH1cbn1cbiJdfQ==
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, signal, computed, Component } from '@angular/core';
2
+ import { Injectable, inject, input, signal, computed, Component } from '@angular/core';
3
3
  import { NgFor } from '@angular/common';
4
4
 
5
5
  class CalendarService {
@@ -75,6 +75,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
75
75
  class CalendarComponent {
76
76
  constructor() {
77
77
  this.calendarService = inject(CalendarService);
78
+ /** 可选。与接口 data.calendarList 一致,用于按日期显示状态(如 AVAILABLE / PURCHASED) */
79
+ this.calendarStates = input([]);
78
80
  this.currentDate = signal(new Date());
79
81
  this.selectedDate = signal(null);
80
82
  this.weekDays = this.calendarService.getWeekDayLabels();
@@ -85,14 +87,27 @@ class CalendarComponent {
85
87
  this.days = computed(() => {
86
88
  const d = this.currentDate();
87
89
  const selected = this.selectedDate();
90
+ const states = this.calendarStates();
91
+ const stateMap = new Map(states.map((s) => [s.date, s]));
88
92
  const days = this.calendarService.getDaysInMonth(d.getFullYear(), d.getMonth());
89
- return days.map((day) => ({
90
- ...day,
91
- isSelected: selected !== null &&
92
- this.calendarService.isSameDay(day.date, selected),
93
- }));
93
+ return days.map((day) => {
94
+ const key = this.formatDateKey(day.date);
95
+ const state = stateMap.get(key);
96
+ return {
97
+ ...day,
98
+ isSelected: selected !== null &&
99
+ this.calendarService.isSameDay(day.date, selected),
100
+ status: state?.status,
101
+ };
102
+ });
94
103
  });
95
104
  }
105
+ formatDateKey(date) {
106
+ const y = date.getFullYear();
107
+ const m = String(date.getMonth() + 1).padStart(2, '0');
108
+ const day = String(date.getDate()).padStart(2, '0');
109
+ return `${y}-${m}-${day}`;
110
+ }
96
111
  prevMonth() {
97
112
  const d = this.currentDate();
98
113
  this.currentDate.set(new Date(d.getFullYear(), d.getMonth() - 1));
@@ -110,11 +125,11 @@ class CalendarComponent {
110
125
  this.selectedDate.set(today);
111
126
  }
112
127
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
113
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CalendarComponent, isStandalone: true, selector: "shdr-calendar", ngImport: i0, template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}\n"] }); }
128
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CalendarComponent, isStandalone: true, selector: "shdr-calendar", inputs: { calendarStates: { classPropertyName: "calendarStates", publicName: "calendarStates", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.status-available]=\"day.status === 'AVAILABLE'\"\n [class.status-purchased]=\"day.status === 'PURCHASED'\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{position:relative;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}.day-cell.status-available{--cal-dot: #22c55e}.day-cell.status-available:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}.day-cell.status-purchased{--cal-dot: #94a3b8}.day-cell.status-purchased:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}\n"] }); }
114
129
  }
115
130
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarComponent, decorators: [{
116
131
  type: Component,
117
- args: [{ selector: 'shdr-calendar', standalone: true, imports: [NgFor], template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}\n"] }]
132
+ args: [{ selector: 'shdr-calendar', standalone: true, imports: [NgFor], template: "<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"\u4E0A\u4E00\u6708\">\n \u2039\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"\u4E0B\u4E00\u6708\">\n \u203A\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">\u4ECA\u5929</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.status-available]=\"day.status === 'AVAILABLE'\"\n [class.status-purchased]=\"day.status === 'PURCHASED'\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n", styles: [":host{display:block}.calendar{--cal-bg: #fff;--cal-border: #e2e8f0;--cal-text: #1e293b;--cal-text-muted: #64748b;--cal-today: #3b82f6;--cal-selected: #2563eb;--cal-selected-text: #fff;--cal-hover: #f1f5f9;max-width:360px;padding:1rem;background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:12px;font-family:system-ui,-apple-system,sans-serif}.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.month-year{margin:0;font-size:1.125rem;font-weight:600;color:var(--cal-text)}.nav-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border:none;background:var(--cal-hover);color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:1.25rem;line-height:1}.nav-btn:hover{background:var(--cal-border)}.today-btn{display:block;width:100%;margin-bottom:1rem;padding:.5rem;border:1px solid var(--cal-border);background:transparent;color:var(--cal-text);border-radius:8px;cursor:pointer;font-size:.875rem}.today-btn:hover{background:var(--cal-hover)}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.weekday{text-align:center;font-size:.75rem;font-weight:600;color:var(--cal-text-muted)}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.day-cell{position:relative;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:var(--cal-text);font-size:.875rem;border-radius:8px;cursor:pointer}.day-cell:hover{background:var(--cal-hover)}.day-cell.other-month{color:var(--cal-text-muted)}.day-cell.today{font-weight:700;color:var(--cal-today)}.day-cell.selected{background:var(--cal-selected);color:var(--cal-selected-text)}.day-cell.selected:hover{background:var(--cal-selected);filter:brightness(1.05)}.day-cell.status-available{--cal-dot: #22c55e}.day-cell.status-available:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}.day-cell.status-purchased{--cal-dot: #94a3b8}.day-cell.status-purchased:after{content:\"\";position:absolute;bottom:4px;left:50%;transform:translate(-50%);width:4px;height:4px;border-radius:50%;background:var(--cal-dot)}\n"] }]
118
133
  }] });
119
134
 
120
135
  /*
@@ -1 +1 @@
1
- {"version":3,"file":"shdr-calendar.mjs","sources":["../../../projects/shdr-calendar/src/lib/calendar.service.ts","../../../projects/shdr-calendar/src/lib/calendar.component.ts","../../../projects/shdr-calendar/src/lib/calendar.component.html","../../../projects/shdr-calendar/src/public-api.ts","../../../projects/shdr-calendar/src/shdr-calendar.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\nexport interface CalendarDay {\n date: Date;\n day: number;\n isCurrentMonth: boolean;\n isToday: boolean;\n isSelected?: boolean;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CalendarService {\n private readonly weekDays = ['日', '一', '二', '三', '四', '五', '六'];\n\n getWeekDayLabels(): string[] {\n return this.weekDays;\n }\n\n getDaysInMonth(year: number, month: number): CalendarDay[] {\n const first = new Date(year, month, 1);\n const last = new Date(year, month + 1, 0);\n const firstDayOfWeek = first.getDay();\n const daysInMonth = last.getDate();\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n const days: CalendarDay[] = [];\n const startPadding = firstDayOfWeek;\n const prevMonth = month === 0 ? 11 : month - 1;\n const prevYear = month === 0 ? year - 1 : year;\n const prevMonthDays = new Date(prevYear, prevMonth + 1, 0).getDate();\n\n for (let i = 0; i < startPadding; i++) {\n const day = prevMonthDays - startPadding + i + 1;\n const date = new Date(prevYear, prevMonth, day);\n days.push({\n date,\n day,\n isCurrentMonth: false,\n isToday: this.isSameDay(date, today),\n });\n }\n\n for (let d = 1; d <= daysInMonth; d++) {\n const date = new Date(year, month, d);\n days.push({\n date,\n day: d,\n isCurrentMonth: true,\n isToday: this.isSameDay(date, today),\n });\n }\n\n const remaining = 42 - days.length;\n const nextMonth = month === 11 ? 0 : month + 1;\n const nextYear = month === 11 ? year + 1 : year;\n for (let d = 1; d <= remaining; d++) {\n const date = new Date(nextYear, nextMonth, d);\n days.push({\n date,\n day: d,\n isCurrentMonth: false,\n isToday: this.isSameDay(date, today),\n });\n }\n\n return days;\n }\n\n isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n }\n\n getMonthYearLabel(year: number, month: number): string {\n return `${year}年${month + 1}月`;\n }\n}\n","import { Component, signal, computed, inject } from '@angular/core';\nimport { NgFor } from '@angular/common';\nimport { CalendarService, type CalendarDay } from './calendar.service';\n\n@Component({\n selector: 'shdr-calendar',\n standalone: true,\n imports: [NgFor],\n templateUrl: './calendar.component.html',\n styleUrl: './calendar.component.scss',\n})\nexport class CalendarComponent {\n private calendarService = inject(CalendarService);\n\n currentDate = signal(new Date());\n selectedDate = signal<Date | null>(null);\n\n weekDays = this.calendarService.getWeekDayLabels();\n\n monthYearLabel = computed(() => {\n const d = this.currentDate();\n return this.calendarService.getMonthYearLabel(d.getFullYear(), d.getMonth());\n });\n\n days = computed(() => {\n const d = this.currentDate();\n const selected = this.selectedDate();\n const days = this.calendarService.getDaysInMonth(\n d.getFullYear(),\n d.getMonth()\n );\n return days.map((day) => ({\n ...day,\n isSelected:\n selected !== null &&\n this.calendarService.isSameDay(day.date, selected),\n }));\n });\n\n prevMonth(): void {\n const d = this.currentDate();\n this.currentDate.set(new Date(d.getFullYear(), d.getMonth() - 1));\n }\n\n nextMonth(): void {\n const d = this.currentDate();\n this.currentDate.set(new Date(d.getFullYear(), d.getMonth() + 1));\n }\n\n selectDay(day: CalendarDay): void {\n this.selectedDate.set(day.date);\n }\n\n goToToday(): void {\n const today = new Date();\n this.currentDate.set(today);\n this.selectedDate.set(today);\n }\n}\n","<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"上一月\">\n ‹\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"下一月\">\n ›\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">今天</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n","/*\n * Public API Surface of shdr-calendar\n */\n\nexport * from './lib/calendar.service';\nexport * from './lib/calendar.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shdr-calendar.mjs","sources":["../../../projects/shdr-calendar/src/lib/calendar.service.ts","../../../projects/shdr-calendar/src/lib/calendar.component.ts","../../../projects/shdr-calendar/src/lib/calendar.component.html","../../../projects/shdr-calendar/src/public-api.ts","../../../projects/shdr-calendar/src/shdr-calendar.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\nexport interface CalendarDay {\n date: Date;\n day: number;\n isCurrentMonth: boolean;\n isToday: boolean;\n isSelected?: boolean;\n}\n\n/** 与接口 data.calendarList 项一致,用于按日期显示状态(如 AVAILABLE / PURCHASED) */\nexport interface CalendarDayState {\n date: string; // 'YYYY-MM-DD'\n status: string; // e.g. 'AVAILABLE' | 'PURCHASED'\n plu?: string;\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CalendarService {\n private readonly weekDays = ['日', '一', '二', '三', '四', '五', '六'];\n\n getWeekDayLabels(): string[] {\n return this.weekDays;\n }\n\n getDaysInMonth(year: number, month: number): CalendarDay[] {\n const first = new Date(year, month, 1);\n const last = new Date(year, month + 1, 0);\n const firstDayOfWeek = first.getDay();\n const daysInMonth = last.getDate();\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n const days: CalendarDay[] = [];\n const startPadding = firstDayOfWeek;\n const prevMonth = month === 0 ? 11 : month - 1;\n const prevYear = month === 0 ? year - 1 : year;\n const prevMonthDays = new Date(prevYear, prevMonth + 1, 0).getDate();\n\n for (let i = 0; i < startPadding; i++) {\n const day = prevMonthDays - startPadding + i + 1;\n const date = new Date(prevYear, prevMonth, day);\n days.push({\n date,\n day,\n isCurrentMonth: false,\n isToday: this.isSameDay(date, today),\n });\n }\n\n for (let d = 1; d <= daysInMonth; d++) {\n const date = new Date(year, month, d);\n days.push({\n date,\n day: d,\n isCurrentMonth: true,\n isToday: this.isSameDay(date, today),\n });\n }\n\n const remaining = 42 - days.length;\n const nextMonth = month === 11 ? 0 : month + 1;\n const nextYear = month === 11 ? year + 1 : year;\n for (let d = 1; d <= remaining; d++) {\n const date = new Date(nextYear, nextMonth, d);\n days.push({\n date,\n day: d,\n isCurrentMonth: false,\n isToday: this.isSameDay(date, today),\n });\n }\n\n return days;\n }\n\n isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n }\n\n getMonthYearLabel(year: number, month: number): string {\n return `${year}年${month + 1}月`;\n }\n}\n","import { Component, signal, computed, inject, input } from '@angular/core';\nimport { NgFor } from '@angular/common';\nimport { CalendarService, type CalendarDay, type CalendarDayState } from './calendar.service';\n\n@Component({\n selector: 'shdr-calendar',\n standalone: true,\n imports: [NgFor],\n templateUrl: './calendar.component.html',\n styleUrl: './calendar.component.scss',\n})\nexport class CalendarComponent {\n private calendarService = inject(CalendarService);\n\n /** 可选。与接口 data.calendarList 一致,用于按日期显示状态(如 AVAILABLE / PURCHASED) */\n calendarStates = input<CalendarDayState[]>([]);\n\n currentDate = signal(new Date());\n selectedDate = signal<Date | null>(null);\n\n weekDays = this.calendarService.getWeekDayLabels();\n\n monthYearLabel = computed(() => {\n const d = this.currentDate();\n return this.calendarService.getMonthYearLabel(d.getFullYear(), d.getMonth());\n });\n\n days = computed(() => {\n const d = this.currentDate();\n const selected = this.selectedDate();\n const states = this.calendarStates();\n const stateMap = new Map(states.map((s) => [s.date, s]));\n const days = this.calendarService.getDaysInMonth(\n d.getFullYear(),\n d.getMonth()\n );\n return days.map((day) => {\n const key = this.formatDateKey(day.date);\n const state = stateMap.get(key);\n return {\n ...day,\n isSelected:\n selected !== null &&\n this.calendarService.isSameDay(day.date, selected),\n status: state?.status,\n };\n });\n });\n\n private formatDateKey(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n }\n\n prevMonth(): void {\n const d = this.currentDate();\n this.currentDate.set(new Date(d.getFullYear(), d.getMonth() - 1));\n }\n\n nextMonth(): void {\n const d = this.currentDate();\n this.currentDate.set(new Date(d.getFullYear(), d.getMonth() + 1));\n }\n\n selectDay(day: CalendarDay): void {\n this.selectedDate.set(day.date);\n }\n\n goToToday(): void {\n const today = new Date();\n this.currentDate.set(today);\n this.selectedDate.set(today);\n }\n}\n","<div class=\"calendar\">\n <header class=\"calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth()\" aria-label=\"上一月\">\n ‹\n </button>\n <h2 class=\"month-year\">{{ monthYearLabel() }}</h2>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" aria-label=\"下一月\">\n ›\n </button>\n </header>\n\n <button type=\"button\" class=\"today-btn\" (click)=\"goToToday()\">今天</button>\n\n <div class=\"weekdays\">\n @for (label of weekDays; track label) {\n <span class=\"weekday\">{{ label }}</span>\n }\n </div>\n\n <div class=\"days-grid\">\n @for (day of days(); track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-cell\"\n [class.other-month]=\"!day.isCurrentMonth\"\n [class.today]=\"day.isToday\"\n [class.selected]=\"day.isSelected\"\n [class.status-available]=\"day.status === 'AVAILABLE'\"\n [class.status-purchased]=\"day.status === 'PURCHASED'\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n }\n </div>\n</div>\n","/*\n * Public API Surface of shdr-calendar\n */\n\nexport * from './lib/calendar.service';\nexport * from './lib/calendar.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,22 +1,26 @@
1
- import { type CalendarDay } from './calendar.service';
1
+ import { type CalendarDay, type CalendarDayState } from './calendar.service';
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class CalendarComponent {
4
4
  private calendarService;
5
+ /** 可选。与接口 data.calendarList 一致,用于按日期显示状态(如 AVAILABLE / PURCHASED) */
6
+ calendarStates: import("@angular/core").InputSignal<CalendarDayState[]>;
5
7
  currentDate: import("@angular/core").WritableSignal<Date>;
6
8
  selectedDate: import("@angular/core").WritableSignal<Date | null>;
7
9
  weekDays: string[];
8
10
  monthYearLabel: import("@angular/core").Signal<string>;
9
11
  days: import("@angular/core").Signal<{
10
12
  isSelected: boolean;
13
+ status: string | undefined;
11
14
  date: Date;
12
15
  day: number;
13
16
  isCurrentMonth: boolean;
14
17
  isToday: boolean;
15
18
  }[]>;
19
+ private formatDateKey;
16
20
  prevMonth(): void;
17
21
  nextMonth(): void;
18
22
  selectDay(day: CalendarDay): void;
19
23
  goToToday(): void;
20
24
  static ɵfac: i0.ɵɵFactoryDeclaration<CalendarComponent, never>;
21
- static ɵcmp: i0.ɵɵComponentDeclaration<CalendarComponent, "shdr-calendar", never, {}, {}, never, never, true, never>;
25
+ static ɵcmp: i0.ɵɵComponentDeclaration<CalendarComponent, "shdr-calendar", never, { "calendarStates": { "alias": "calendarStates"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
22
26
  }
@@ -6,6 +6,12 @@ export interface CalendarDay {
6
6
  isToday: boolean;
7
7
  isSelected?: boolean;
8
8
  }
9
+ /** 与接口 data.calendarList 项一致,用于按日期显示状态(如 AVAILABLE / PURCHASED) */
10
+ export interface CalendarDayState {
11
+ date: string;
12
+ status: string;
13
+ plu?: string;
14
+ }
9
15
  export declare class CalendarService {
10
16
  private readonly weekDays;
11
17
  getWeekDayLabels(): string[];
package/package.json CHANGED
@@ -1,16 +1,12 @@
1
1
  {
2
2
  "name": "shdr-calendar",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Angular 日历组件,支持月视图、选日与今天快捷跳转",
5
5
  "keywords": [
6
6
  "angular",
7
7
  "calendar",
8
8
  "component"
9
9
  ],
10
- "repository": {
11
- "type": "git",
12
- "url": "https://github.disney.com/SHDR-Projects/shdr-calendar-lib.git"
13
- },
14
10
  "peerDependencies": {
15
11
  "@angular/common": "^17.0.0",
16
12
  "@angular/core": "^17.0.0"