shdr-calendar 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # ShdrCalendar
2
+
3
+ This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.0.
4
+
5
+ ## Code scaffolding
6
+
7
+ Run `ng generate component component-name --project shdr-calendar` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project shdr-calendar`.
8
+ > Note: Don't forget to add `--project shdr-calendar` or else it will be added to the default project in your `angular.json` file.
9
+
10
+ ## Build
11
+
12
+ Run `ng build shdr-calendar` to build the project. The build artifacts will be stored in the `dist/` directory.
13
+
14
+ ## Publishing
15
+
16
+ After building your library with `ng build shdr-calendar`, go to the dist folder `cd dist/shdr-calendar` and run `npm publish`.
17
+
18
+ ## Running unit tests
19
+
20
+ Run `ng test shdr-calendar` to execute the unit tests via [Karma](https://karma-runner.github.io).
21
+
22
+ ## Further help
23
+
24
+ To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
@@ -0,0 +1,49 @@
1
+ import { Component, signal, computed, inject } from '@angular/core';
2
+ import { NgFor } from '@angular/common';
3
+ import { CalendarService } from './calendar.service';
4
+ import * as i0 from "@angular/core";
5
+ export class CalendarComponent {
6
+ constructor() {
7
+ this.calendarService = inject(CalendarService);
8
+ this.currentDate = signal(new Date());
9
+ this.selectedDate = signal(null);
10
+ this.weekDays = this.calendarService.getWeekDayLabels();
11
+ this.monthYearLabel = computed(() => {
12
+ const d = this.currentDate();
13
+ return this.calendarService.getMonthYearLabel(d.getFullYear(), d.getMonth());
14
+ });
15
+ this.days = computed(() => {
16
+ const d = this.currentDate();
17
+ const selected = this.selectedDate();
18
+ 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
+ }));
24
+ });
25
+ }
26
+ prevMonth() {
27
+ const d = this.currentDate();
28
+ this.currentDate.set(new Date(d.getFullYear(), d.getMonth() - 1));
29
+ }
30
+ nextMonth() {
31
+ const d = this.currentDate();
32
+ this.currentDate.set(new Date(d.getFullYear(), d.getMonth() + 1));
33
+ }
34
+ selectDay(day) {
35
+ this.selectedDate.set(day.date);
36
+ }
37
+ goToToday() {
38
+ const today = new Date();
39
+ this.currentDate.set(today);
40
+ this.selectedDate.set(today);
41
+ }
42
+ 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"] }); }
44
+ }
45
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarComponent, decorators: [{
46
+ 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"] }]
48
+ }] });
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvc2hkci1jYWxlbmRhci9zcmMvbGliL2NhbGVuZGFyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL2xpYi9jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZUFBZSxFQUFvQixNQUFNLG9CQUFvQixDQUFDOztBQVN2RSxNQUFNLE9BQU8saUJBQWlCO0lBUDlCO1FBUVUsb0JBQWUsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFbEQsZ0JBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLGlCQUFZLEdBQUcsTUFBTSxDQUFjLElBQUksQ0FBQyxDQUFDO1FBRXpDLGFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFbkQsbUJBQWMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQzdCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM3QixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO1FBRUgsU0FBSSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FDOUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUNmLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FDYixDQUFDO1lBQ0YsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN4QixHQUFHLEdBQUc7Z0JBQ04sVUFBVSxFQUNSLFFBQVEsS0FBSyxJQUFJO29CQUNqQixJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQzthQUNyRCxDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0tBcUJKO0lBbkJDLFNBQVM7UUFDUCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRCxTQUFTO1FBQ1AsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQWdCO1FBQ3hCLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsU0FBUztRQUNQLE1BQU0sS0FBSyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQzsrR0E5Q1UsaUJBQWlCO21HQUFqQixpQkFBaUIseUVDWDlCLG9oQ0FrQ0E7OzRGRHZCYSxpQkFBaUI7a0JBUDdCLFNBQVM7K0JBQ0UsZUFBZSxjQUNiLElBQUksV0FDUCxDQUFDLEtBQUssQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgc2lnbmFsLCBjb21wdXRlZCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ0ZvciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDYWxlbmRhclNlcnZpY2UsIHR5cGUgQ2FsZW5kYXJEYXkgfSBmcm9tICcuL2NhbGVuZGFyLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzaGRyLWNhbGVuZGFyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW05nRm9yXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJDb21wb25lbnQge1xuICBwcml2YXRlIGNhbGVuZGFyU2VydmljZSA9IGluamVjdChDYWxlbmRhclNlcnZpY2UpO1xuXG4gIGN1cnJlbnREYXRlID0gc2lnbmFsKG5ldyBEYXRlKCkpO1xuICBzZWxlY3RlZERhdGUgPSBzaWduYWw8RGF0ZSB8IG51bGw+KG51bGwpO1xuXG4gIHdlZWtEYXlzID0gdGhpcy5jYWxlbmRhclNlcnZpY2UuZ2V0V2Vla0RheUxhYmVscygpO1xuXG4gIG1vbnRoWWVhckxhYmVsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmN1cnJlbnREYXRlKCk7XG4gICAgcmV0dXJuIHRoaXMuY2FsZW5kYXJTZXJ2aWNlLmdldE1vbnRoWWVhckxhYmVsKGQuZ2V0RnVsbFllYXIoKSwgZC5nZXRNb250aCgpKTtcbiAgfSk7XG5cbiAgZGF5cyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5jdXJyZW50RGF0ZSgpO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZERhdGUoKTtcbiAgICBjb25zdCBkYXlzID0gdGhpcy5jYWxlbmRhclNlcnZpY2UuZ2V0RGF5c0luTW9udGgoXG4gICAgICBkLmdldEZ1bGxZZWFyKCksXG4gICAgICBkLmdldE1vbnRoKClcbiAgICApO1xuICAgIHJldHVybiBkYXlzLm1hcCgoZGF5KSA9PiAoe1xuICAgICAgLi4uZGF5LFxuICAgICAgaXNTZWxlY3RlZDpcbiAgICAgICAgc2VsZWN0ZWQgIT09IG51bGwgJiZcbiAgICAgICAgdGhpcy5jYWxlbmRhclNlcnZpY2UuaXNTYW1lRGF5KGRheS5kYXRlLCBzZWxlY3RlZCksXG4gICAgfSkpO1xuICB9KTtcblxuICBwcmV2TW9udGgoKTogdm9pZCB7XG4gICAgY29uc3QgZCA9IHRoaXMuY3VycmVudERhdGUoKTtcbiAgICB0aGlzLmN1cnJlbnREYXRlLnNldChuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCksIGQuZ2V0TW9udGgoKSAtIDEpKTtcbiAgfVxuXG4gIG5leHRNb250aCgpOiB2b2lkIHtcbiAgICBjb25zdCBkID0gdGhpcy5jdXJyZW50RGF0ZSgpO1xuICAgIHRoaXMuY3VycmVudERhdGUuc2V0KG5ldyBEYXRlKGQuZ2V0RnVsbFllYXIoKSwgZC5nZXRNb250aCgpICsgMSkpO1xuICB9XG5cbiAgc2VsZWN0RGF5KGRheTogQ2FsZW5kYXJEYXkpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZS5zZXQoZGF5LmRhdGUpO1xuICB9XG5cbiAgZ29Ub1RvZGF5KCk6IHZvaWQge1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICB0aGlzLmN1cnJlbnREYXRlLnNldCh0b2RheSk7XG4gICAgdGhpcy5zZWxlY3RlZERhdGUuc2V0KHRvZGF5KTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNhbGVuZGFyXCI+XG4gIDxoZWFkZXIgY2xhc3M9XCJjYWxlbmRhci1oZWFkZXJcIj5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cIm5hdi1idG5cIiAoY2xpY2spPVwicHJldk1vbnRoKClcIiBhcmlhLWxhYmVsPVwi5LiK5LiA5pyIXCI+XG4gICAgICDigLlcbiAgICA8L2J1dHRvbj5cbiAgICA8aDIgY2xhc3M9XCJtb250aC15ZWFyXCI+e3sgbW9udGhZZWFyTGFiZWwoKSB9fTwvaDI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJuYXYtYnRuXCIgKGNsaWNrKT1cIm5leHRNb250aCgpXCIgYXJpYS1sYWJlbD1cIuS4i+S4gOaciFwiPlxuICAgICAg4oC6XG4gICAgPC9idXR0b24+XG4gIDwvaGVhZGVyPlxuXG4gIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidG9kYXktYnRuXCIgKGNsaWNrKT1cImdvVG9Ub2RheSgpXCI+5LuK5aSpPC9idXR0b24+XG5cbiAgPGRpdiBjbGFzcz1cIndlZWtkYXlzXCI+XG4gICAgQGZvciAobGFiZWwgb2Ygd2Vla0RheXM7IHRyYWNrIGxhYmVsKSB7XG4gICAgICA8c3BhbiBjbGFzcz1cIndlZWtkYXlcIj57eyBsYWJlbCB9fTwvc3Bhbj5cbiAgICB9XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJkYXlzLWdyaWRcIj5cbiAgICBAZm9yIChkYXkgb2YgZGF5cygpOyB0cmFjayBkYXkuZGF0ZS5nZXRUaW1lKCkpIHtcbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiZGF5LWNlbGxcIlxuICAgICAgICBbY2xhc3Mub3RoZXItbW9udGhdPVwiIWRheS5pc0N1cnJlbnRNb250aFwiXG4gICAgICAgIFtjbGFzcy50b2RheV09XCJkYXkuaXNUb2RheVwiXG4gICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkYXkuaXNTZWxlY3RlZFwiXG4gICAgICAgIChjbGljayk9XCJzZWxlY3REYXkoZGF5KVwiXG4gICAgICA+XG4gICAgICAgIHt7IGRheS5kYXkgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIH1cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
@@ -0,0 +1,72 @@
1
+ import { Injectable } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class CalendarService {
4
+ constructor() {
5
+ this.weekDays = ['日', '一', '二', '三', '四', '五', '六'];
6
+ }
7
+ getWeekDayLabels() {
8
+ return this.weekDays;
9
+ }
10
+ getDaysInMonth(year, month) {
11
+ const first = new Date(year, month, 1);
12
+ const last = new Date(year, month + 1, 0);
13
+ const firstDayOfWeek = first.getDay();
14
+ const daysInMonth = last.getDate();
15
+ const today = new Date();
16
+ today.setHours(0, 0, 0, 0);
17
+ const days = [];
18
+ const startPadding = firstDayOfWeek;
19
+ const prevMonth = month === 0 ? 11 : month - 1;
20
+ const prevYear = month === 0 ? year - 1 : year;
21
+ const prevMonthDays = new Date(prevYear, prevMonth + 1, 0).getDate();
22
+ for (let i = 0; i < startPadding; i++) {
23
+ const day = prevMonthDays - startPadding + i + 1;
24
+ const date = new Date(prevYear, prevMonth, day);
25
+ days.push({
26
+ date,
27
+ day,
28
+ isCurrentMonth: false,
29
+ isToday: this.isSameDay(date, today),
30
+ });
31
+ }
32
+ for (let d = 1; d <= daysInMonth; d++) {
33
+ const date = new Date(year, month, d);
34
+ days.push({
35
+ date,
36
+ day: d,
37
+ isCurrentMonth: true,
38
+ isToday: this.isSameDay(date, today),
39
+ });
40
+ }
41
+ const remaining = 42 - days.length;
42
+ const nextMonth = month === 11 ? 0 : month + 1;
43
+ const nextYear = month === 11 ? year + 1 : year;
44
+ for (let d = 1; d <= remaining; d++) {
45
+ const date = new Date(nextYear, nextMonth, d);
46
+ days.push({
47
+ date,
48
+ day: d,
49
+ isCurrentMonth: false,
50
+ isToday: this.isSameDay(date, today),
51
+ });
52
+ }
53
+ return days;
54
+ }
55
+ isSameDay(a, b) {
56
+ return (a.getFullYear() === b.getFullYear() &&
57
+ a.getMonth() === b.getMonth() &&
58
+ a.getDate() === b.getDate());
59
+ }
60
+ getMonthYearLabel(year, month) {
61
+ return `${year}年${month + 1}月`;
62
+ }
63
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
64
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarService, providedIn: 'root' }); }
65
+ }
66
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarService, decorators: [{
67
+ type: Injectable,
68
+ args: [{
69
+ providedIn: 'root',
70
+ }]
71
+ }] });
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL2xpYi9jYWxlbmRhci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBYTNDLE1BQU0sT0FBTyxlQUFlO0lBSDVCO1FBSW1CLGFBQVEsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBb0VqRTtJQWxFQyxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELGNBQWMsQ0FBQyxJQUFZLEVBQUUsS0FBYTtRQUN4QyxNQUFNLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN6QixLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTNCLE1BQU0sSUFBSSxHQUFrQixFQUFFLENBQUM7UUFDL0IsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDO1FBQ3BDLE1BQU0sU0FBUyxHQUFHLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENB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ZTtrQkFIM0IsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJEYXkge1xuICBkYXRlOiBEYXRlO1xuICBkYXk6IG51bWJlcjtcbiAgaXNDdXJyZW50TW9udGg6IGJvb2xlYW47XG4gIGlzVG9kYXk6IGJvb2xlYW47XG4gIGlzU2VsZWN0ZWQ/OiBib29sZWFuO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWVrRGF5cyA9IFsn5pelJywgJ+S4gCcsICfkuownLCAn5LiJJywgJ+WbmycsICfkupQnLCAn5YWtJ107XG5cbiAgZ2V0V2Vla0RheUxhYmVscygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMud2Vla0RheXM7XG4gIH1cblxuICBnZXREYXlzSW5Nb250aCh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBDYWxlbmRhckRheVtdIHtcbiAgICBjb25zdCBmaXJzdCA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAxKTtcbiAgICBjb25zdCBsYXN0ID0gbmV3IERhdGUoeWVhciwgbW9udGggKyAxLCAwKTtcbiAgICBjb25zdCBmaXJzdERheU9mV2VlayA9IGZpcnN0LmdldERheSgpO1xuICAgIGNvbnN0IGRheXNJbk1vbnRoID0gbGFzdC5nZXREYXRlKCk7XG4gICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuICAgIHRvZGF5LnNldEhvdXJzKDAsIDAsIDAsIDApO1xuXG4gICAgY29uc3QgZGF5czogQ2FsZW5kYXJEYXlbXSA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0UGFkZGluZyA9IGZpcnN0RGF5T2ZXZWVrO1xuICAgIGNvbnN0IHByZXZNb250aCA9IG1vbnRoID09PSAwID8gMTEgOiBtb250aCAtIDE7XG4gICAgY29uc3QgcHJldlllYXIgPSBtb250aCA9PT0gMCA/IHllYXIgLSAxIDogeWVhcjtcbiAgICBjb25zdCBwcmV2TW9udGhEYXlzID0gbmV3IERhdGUocHJldlllYXIsIHByZXZNb250aCArIDEsIDApLmdldERhdGUoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhcnRQYWRkaW5nOyBpKyspIHtcbiAgICAgIGNvbnN0IGRheSA9IHByZXZNb250aERheXMgLSBzdGFydFBhZGRpbmcgKyBpICsgMTtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShwcmV2WWVhciwgcHJldk1vbnRoLCBkYXkpO1xuICAgICAgZGF5cy5wdXNoKHtcbiAgICAgICAgZGF0ZSxcbiAgICAgICAgZGF5LFxuICAgICAgICBpc0N1cnJlbnRNb250aDogZmFsc2UsXG4gICAgICAgIGlzVG9kYXk6IHRoaXMuaXNTYW1lRGF5KGRhdGUsIHRvZGF5KSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZvciAobGV0IGQgPSAxOyBkIDw9IGRheXNJbk1vbnRoOyBkKyspIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZCk7XG4gICAgICBkYXlzLnB1c2goe1xuICAgICAgICBkYXRlLFxuICAgICAgICBkYXk6IGQsXG4gICAgICAgIGlzQ3VycmVudE1vbnRoOiB0cnVlLFxuICAgICAgICBpc1RvZGF5OiB0aGlzLmlzU2FtZURheShkYXRlLCB0b2RheSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCByZW1haW5pbmcgPSA0MiAtIGRheXMubGVuZ3RoO1xuICAgIGNvbnN0IG5leHRNb250aCA9IG1vbnRoID09PSAxMSA/IDAgOiBtb250aCArIDE7XG4gICAgY29uc3QgbmV4dFllYXIgPSBtb250aCA9PT0gMTEgPyB5ZWFyICsgMSA6IHllYXI7XG4gICAgZm9yIChsZXQgZCA9IDE7IGQgPD0gcmVtYWluaW5nOyBkKyspIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShuZXh0WWVhciwgbmV4dE1vbnRoLCBkKTtcbiAgICAgIGRheXMucHVzaCh7XG4gICAgICAgIGRhdGUsXG4gICAgICAgIGRheTogZCxcbiAgICAgICAgaXNDdXJyZW50TW9udGg6IGZhbHNlLFxuICAgICAgICBpc1RvZGF5OiB0aGlzLmlzU2FtZURheShkYXRlLCB0b2RheSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF5cztcbiAgfVxuXG4gIGlzU2FtZURheShhOiBEYXRlLCBiOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGEuZ2V0RnVsbFllYXIoKSA9PT0gYi5nZXRGdWxsWWVhcigpICYmXG4gICAgICBhLmdldE1vbnRoKCkgPT09IGIuZ2V0TW9udGgoKSAmJlxuICAgICAgYS5nZXREYXRlKCkgPT09IGIuZ2V0RGF0ZSgpXG4gICAgKTtcbiAgfVxuXG4gIGdldE1vbnRoWWVhckxhYmVsKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3llYXJ95bm0JHttb250aCArIDF95pyIYDtcbiAgfVxufVxuIl19
@@ -0,0 +1,6 @@
1
+ /*
2
+ * Public API Surface of shdr-calendar
3
+ */
4
+ export * from './lib/calendar.service';
5
+ export * from './lib/calendar.component';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIHNoZHItY2FsZW5kYXJcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jYWxlbmRhci5zZXJ2aWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NhbGVuZGFyLmNvbXBvbmVudCc7XG4iXX0=
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public-api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hkci1jYWxlbmRhci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3NoZHItY2FsZW5kYXIvc3JjL3NoZHItY2FsZW5kYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
@@ -0,0 +1,129 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, inject, signal, computed, Component } from '@angular/core';
3
+ import { NgFor } from '@angular/common';
4
+
5
+ class CalendarService {
6
+ constructor() {
7
+ this.weekDays = ['日', '一', '二', '三', '四', '五', '六'];
8
+ }
9
+ getWeekDayLabels() {
10
+ return this.weekDays;
11
+ }
12
+ getDaysInMonth(year, month) {
13
+ const first = new Date(year, month, 1);
14
+ const last = new Date(year, month + 1, 0);
15
+ const firstDayOfWeek = first.getDay();
16
+ const daysInMonth = last.getDate();
17
+ const today = new Date();
18
+ today.setHours(0, 0, 0, 0);
19
+ const days = [];
20
+ const startPadding = firstDayOfWeek;
21
+ const prevMonth = month === 0 ? 11 : month - 1;
22
+ const prevYear = month === 0 ? year - 1 : year;
23
+ const prevMonthDays = new Date(prevYear, prevMonth + 1, 0).getDate();
24
+ for (let i = 0; i < startPadding; i++) {
25
+ const day = prevMonthDays - startPadding + i + 1;
26
+ const date = new Date(prevYear, prevMonth, day);
27
+ days.push({
28
+ date,
29
+ day,
30
+ isCurrentMonth: false,
31
+ isToday: this.isSameDay(date, today),
32
+ });
33
+ }
34
+ for (let d = 1; d <= daysInMonth; d++) {
35
+ const date = new Date(year, month, d);
36
+ days.push({
37
+ date,
38
+ day: d,
39
+ isCurrentMonth: true,
40
+ isToday: this.isSameDay(date, today),
41
+ });
42
+ }
43
+ const remaining = 42 - days.length;
44
+ const nextMonth = month === 11 ? 0 : month + 1;
45
+ const nextYear = month === 11 ? year + 1 : year;
46
+ for (let d = 1; d <= remaining; d++) {
47
+ const date = new Date(nextYear, nextMonth, d);
48
+ days.push({
49
+ date,
50
+ day: d,
51
+ isCurrentMonth: false,
52
+ isToday: this.isSameDay(date, today),
53
+ });
54
+ }
55
+ return days;
56
+ }
57
+ isSameDay(a, b) {
58
+ return (a.getFullYear() === b.getFullYear() &&
59
+ a.getMonth() === b.getMonth() &&
60
+ a.getDate() === b.getDate());
61
+ }
62
+ getMonthYearLabel(year, month) {
63
+ return `${year}年${month + 1}月`;
64
+ }
65
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
66
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarService, providedIn: 'root' }); }
67
+ }
68
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarService, decorators: [{
69
+ type: Injectable,
70
+ args: [{
71
+ providedIn: 'root',
72
+ }]
73
+ }] });
74
+
75
+ class CalendarComponent {
76
+ constructor() {
77
+ this.calendarService = inject(CalendarService);
78
+ this.currentDate = signal(new Date());
79
+ this.selectedDate = signal(null);
80
+ this.weekDays = this.calendarService.getWeekDayLabels();
81
+ this.monthYearLabel = computed(() => {
82
+ const d = this.currentDate();
83
+ return this.calendarService.getMonthYearLabel(d.getFullYear(), d.getMonth());
84
+ });
85
+ this.days = computed(() => {
86
+ const d = this.currentDate();
87
+ const selected = this.selectedDate();
88
+ 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
+ }));
94
+ });
95
+ }
96
+ prevMonth() {
97
+ const d = this.currentDate();
98
+ this.currentDate.set(new Date(d.getFullYear(), d.getMonth() - 1));
99
+ }
100
+ nextMonth() {
101
+ const d = this.currentDate();
102
+ this.currentDate.set(new Date(d.getFullYear(), d.getMonth() + 1));
103
+ }
104
+ selectDay(day) {
105
+ this.selectedDate.set(day.date);
106
+ }
107
+ goToToday() {
108
+ const today = new Date();
109
+ this.currentDate.set(today);
110
+ this.selectedDate.set(today);
111
+ }
112
+ 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"] }); }
114
+ }
115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalendarComponent, decorators: [{
116
+ 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"] }]
118
+ }] });
119
+
120
+ /*
121
+ * Public API Surface of shdr-calendar
122
+ */
123
+
124
+ /**
125
+ * Generated bundle index. Do not edit.
126
+ */
127
+
128
+ export { CalendarComponent, CalendarService };
129
+ //# sourceMappingURL=shdr-calendar.mjs.map
@@ -0,0 +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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"}
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="shdr-calendar" />
5
+ export * from './public-api';
@@ -0,0 +1,22 @@
1
+ import { type CalendarDay } from './calendar.service';
2
+ import * as i0 from "@angular/core";
3
+ export declare class CalendarComponent {
4
+ private calendarService;
5
+ currentDate: import("@angular/core").WritableSignal<Date>;
6
+ selectedDate: import("@angular/core").WritableSignal<Date | null>;
7
+ weekDays: string[];
8
+ monthYearLabel: import("@angular/core").Signal<string>;
9
+ days: import("@angular/core").Signal<{
10
+ isSelected: boolean;
11
+ date: Date;
12
+ day: number;
13
+ isCurrentMonth: boolean;
14
+ isToday: boolean;
15
+ }[]>;
16
+ prevMonth(): void;
17
+ nextMonth(): void;
18
+ selectDay(day: CalendarDay): void;
19
+ goToToday(): void;
20
+ static ɵfac: i0.ɵɵFactoryDeclaration<CalendarComponent, never>;
21
+ static ɵcmp: i0.ɵɵComponentDeclaration<CalendarComponent, "shdr-calendar", never, {}, {}, never, never, true, never>;
22
+ }
@@ -0,0 +1,17 @@
1
+ import * as i0 from "@angular/core";
2
+ export interface CalendarDay {
3
+ date: Date;
4
+ day: number;
5
+ isCurrentMonth: boolean;
6
+ isToday: boolean;
7
+ isSelected?: boolean;
8
+ }
9
+ export declare class CalendarService {
10
+ private readonly weekDays;
11
+ getWeekDayLabels(): string[];
12
+ getDaysInMonth(year: number, month: number): CalendarDay[];
13
+ isSameDay(a: Date, b: Date): boolean;
14
+ getMonthYearLabel(year: number, month: number): string;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<CalendarService, never>;
16
+ static ɵprov: i0.ɵɵInjectableDeclaration<CalendarService>;
17
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "shdr-calendar",
3
+ "version": "0.0.1",
4
+ "description": "Angular 日历组件,支持月视图、选日与今天快捷跳转",
5
+ "keywords": [
6
+ "angular",
7
+ "calendar",
8
+ "component"
9
+ ],
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.disney.com/SHDR-Projects/shdr-calendar-lib.git"
13
+ },
14
+ "peerDependencies": {
15
+ "@angular/common": "^17.0.0",
16
+ "@angular/core": "^17.0.0"
17
+ },
18
+ "dependencies": {
19
+ "tslib": "^2.3.0"
20
+ },
21
+ "sideEffects": false,
22
+ "publishConfig": {
23
+ "registry": "https://registry.npmjs.org/"
24
+ },
25
+ "module": "fesm2022/shdr-calendar.mjs",
26
+ "typings": "index.d.ts",
27
+ "exports": {
28
+ "./package.json": {
29
+ "default": "./package.json"
30
+ },
31
+ ".": {
32
+ "types": "./index.d.ts",
33
+ "esm2022": "./esm2022/shdr-calendar.mjs",
34
+ "esm": "./esm2022/shdr-calendar.mjs",
35
+ "default": "./fesm2022/shdr-calendar.mjs"
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,2 @@
1
+ export * from './lib/calendar.service';
2
+ export * from './lib/calendar.component';