@progressive-development/pd-calendar 0.5.4 → 0.6.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/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@progressive-development/pd-calendar",
3
- "description": "progressive development calendar web component",
3
+ "version": "0.6.1",
4
+ "description": "Webcomponent for calendar",
4
5
  "author": "PD Progressive Development",
5
6
  "license": "SEE LICENSE IN LICENSE",
6
- "version": "0.5.4",
7
7
  "main": "./dist/index.js",
8
8
  "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
9
10
  "exports": {
10
11
  ".": "./dist/index.js",
11
12
  "./pd-calendar": "./dist/pd-calendar.js",
@@ -20,70 +21,53 @@
20
21
  "LICENSE"
21
22
  ],
22
23
  "scripts": {
23
- "analyze": "cem analyze --litelement",
24
+ "analyze": "cem analyze --litelement --exclude dist,demo",
24
25
  "start": "vite",
25
26
  "build": "vite build",
26
27
  "preview": "vite preview",
27
- "lint": "eslint --ext .js,.html . --ignore-path .gitignore && prettier \"**/*.{js,html}\" --check --ignore-path .gitignore",
28
- "format": "eslint --ext .js,.html . --fix --ignore-path .gitignore && prettier \"**/*.{js,html}\" --write --ignore-path .gitignore",
28
+ "clean": "rm -rf dist",
29
+ "lint": "eslint --ext .ts,.html src --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
30
+ "format": "eslint --ext .ts,.html src --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
29
31
  "test": "vitest run --coverage",
30
32
  "test:watch": "vitest --watch",
33
+ "check": "npm run lint && npm run build",
34
+ "prepublishOnly": "npm run clean && npm run check",
31
35
  "localizeExtract": "lit-localize extract",
32
36
  "localizeBuild": "lit-localize build",
33
37
  "storybook": "storybook dev -p 6006",
34
38
  "build-storybook": "storybook build"
35
39
  },
36
40
  "dependencies": {
37
- "@lit/localize": "^0.11.4",
38
- "@progressive-development/pd-icon": "^0.5.0",
39
- "@progressive-development/pd-shared-styles": "^0.1.1",
41
+ "@lit/localize": "^0.12.2",
42
+ "@progressive-development/pd-icon": "^0.6.3",
43
+ "@progressive-development/pd-shared-styles": "^0.2.1",
40
44
  "fecha": "^4.2.3",
41
- "lit": "^2.8.0"
45
+ "lit": "^3.3.0"
42
46
  },
43
47
  "devDependencies": {
44
- "@chromatic-com/storybook": "^1.3.4",
48
+ "@chromatic-com/storybook": "^1.9.0",
45
49
  "@custom-elements-manifest/analyzer": "^0.4.17",
46
50
  "@lit/localize-tools": "^0.6.10",
47
- "@storybook/addon-essentials": "^8.0.10",
48
- "@storybook/addon-links": "^8.0.10",
51
+ "@storybook/addon-essentials": "^8.6.14",
52
+ "@storybook/addon-links": "^8.6.14",
49
53
  "@storybook/blocks": "^8.0.10",
50
- "@storybook/test": "^8.0.10",
54
+ "@storybook/test": "^8.6.14",
51
55
  "@storybook/web-components": "^8.0.10",
52
- "@storybook/web-components-vite": "^8.0.10",
53
- "eslint": "^7.32.0",
54
- "eslint-config-prettier": "^8.10.0",
56
+ "@storybook/web-components-vite": "^8.6.14",
57
+ "@typescript-eslint/eslint-plugin": "^8.32.1",
58
+ "@typescript-eslint/parser": "^8.32.1",
59
+ "eslint": "^8.57.1",
60
+ "eslint-config-prettier": "^9.1.0",
55
61
  "eslint-plugin-storybook": "^0.8.0",
56
- "husky": "^4.3.8",
57
- "lint-staged": "^10.5.4",
58
- "prettier": "^2.8.8",
59
- "rollup-plugin-visualizer": "^5.13.1",
60
- "storybook": "^8.0.10",
61
- "vite": "^5.4.11",
62
- "vitest": "^2.1.8"
62
+ "prettier": "^3.5.3",
63
+ "rollup-plugin-visualizer": "^5.14.0",
64
+ "storybook": "^8.6.14",
65
+ "typescript": "^5.8.3",
66
+ "vite": "^5.4.19",
67
+ "vite-plugin-dts": "^4.5.4",
68
+ "vitest": "^2.1.9"
63
69
  },
64
70
  "customElements": "custom-elements.json",
65
- "eslintConfig": {
66
- "extends": [
67
- "@open-wc",
68
- "prettier",
69
- "plugin:storybook/recommended"
70
- ]
71
- },
72
- "prettier": {
73
- "singleQuote": true,
74
- "arrowParens": "avoid"
75
- },
76
- "husky": {
77
- "hooks": {
78
- "pre-commit": "lint-staged"
79
- }
80
- },
81
- "lint-staged": {
82
- "*.js": [
83
- "eslint --fix",
84
- "prettier --write"
85
- ]
86
- },
87
71
  "keywords": [
88
72
  "pd",
89
73
  "progressive",
@@ -1,513 +0,0 @@
1
- import { LitElement, css, html } from "lit";
2
- import { msg, updateWhenLocaleChanges } from "@lit/localize";
3
- import { format } from "fecha";
4
- import "@progressive-development/pd-icon/pd-icon";
5
- import { PDColorStyles, PDFontStyles } from "@progressive-development/pd-shared-styles";
6
- import "./PdCalendarCell.js";
7
- import { PdYearPopup } from "./PdYearPopup.js";
8
- /**
9
- * @license
10
- * Copyright (c) 2021 PD Progressive Development UG. All rights reserved.
11
- */
12
- const TOUCH_MIN_MOVE = 70;
13
- const loadLocales = () => ({
14
- monthNames: [
15
- msg("Januar", { id: "pd.datepicker.month.jan" }),
16
- msg("Februar", { id: "pd.datepicker.month.feb" }),
17
- msg("März", { id: "pd.datepicker.month.mar" }),
18
- msg("April", { id: "pd.datepicker.month.apr" }),
19
- msg("Mai", { id: "pd.datepicker.month.may" }),
20
- msg("Juni", { id: "pd.datepicker.month.jun" }),
21
- msg("Juli", { id: "pd.datepicker.month.jul" }),
22
- msg("August", { id: "pd.datepicker.month.aug" }),
23
- msg("September", { id: "pd.datepicker.month.sep" }),
24
- msg("Oktober", { id: "pd.datepicker.month.oct" }),
25
- msg("November", { id: "pd.datepicker.month.nov" }),
26
- msg("Dezember", { id: "pd.datepicker.month.dec" })
27
- ],
28
- weekdays: [
29
- msg("Sonntag", { id: "pd.datepicker.day.sun" }),
30
- msg("Montag", { id: "pd.datepicker.day.mon" }),
31
- msg("Dienstag", { id: "pd.datepicker.day.tue" }),
32
- msg("Mittwoch", { id: "pd.datepicker.day.wed" }),
33
- msg("Donnerstag", { id: "pd.datepicker.day.thi" }),
34
- msg("Freitag", { id: "pd.datepicker.day.fri" }),
35
- msg("Samstag", { id: "pd.datepicker.day.sat" })
36
- ],
37
- weekdaysShort: [
38
- msg("Mo", { id: "pd.datepicker.shortday.mon" }),
39
- msg("Di", { id: "pd.datepicker.shortday.tue" }),
40
- msg("Mi", { id: "pd.datepicker.shortday.wed" }),
41
- msg("Do", { id: "pd.datepicker.shortday.thi" }),
42
- msg("Fr", { id: "pd.datepicker.shortday.fri" }),
43
- msg("Sa", { id: "pd.datepicker.shortday.sat" }),
44
- msg("So", { id: "pd.datepicker.shortday.sun" })
45
- ]
46
- });
47
- const LOCALES = loadLocales();
48
- const VIEW_LIST = 1;
49
- const VIEW_MONTH = 2;
50
- const VIEW_WEEK = 3;
51
- const isToday = (someDate) => {
52
- if (!someDate) {
53
- return false;
54
- }
55
- const today = /* @__PURE__ */ new Date();
56
- return someDate.getDate() === today.getDate() && someDate.getMonth() === today.getMonth() && someDate.getFullYear() === today.getFullYear();
57
- };
58
- const isSelected = (someDate1, someDate2) => {
59
- if (!someDate1 || !someDate2) {
60
- return false;
61
- }
62
- return someDate1.getDate() === someDate2.getDate() && someDate1.getMonth() === someDate2.getMonth() && someDate1.getFullYear() === someDate2.getFullYear();
63
- };
64
- class PdCalendar extends LitElement {
65
- /**
66
- * Fired when next or prev month clicked
67
- * @event change-month
68
- */
69
- /**
70
- * Fired when date with info element clicked => At the moment only for those ones
71
- * @event select-date
72
- */
73
- /**
74
- * Fired when mouse entered date cell, detail contains date (Date) and dateKey(string).
75
- * @event mouse-enter-date
76
- */
77
- /**
78
- * Fired when date leaves date cell
79
- * @event mouse-leave-date
80
- */
81
- static get properties() {
82
- return {
83
- refDate: { type: Object },
84
- selectableDates: { type: Boolean },
85
- withYearPopup: { type: Array },
86
- withWheelNavigation: { type: Boolean },
87
- withTouchNavigation: { type: Boolean },
88
- showSelection: { type: Boolean },
89
- hideWeekend: { type: Boolean, reflect: true },
90
- prevMonthConstraint: { type: Number },
91
- nextMonthConstraint: { type: Number },
92
- data: { type: Object },
93
- /**
94
- * CSS class for day number inside the cell, top-left and center available
95
- */
96
- numberClass: { type: String },
97
- _currentDate: { type: Object },
98
- _viewType: { type: Number },
99
- _wheelDelta: { type: Number, state: true }
100
- };
101
- }
102
- static get styles() {
103
- return [
104
- PDColorStyles,
105
- PDFontStyles,
106
- css`
107
- :host {
108
-
109
- --my-cell-height: var(--pd-calendar-cell-height, 70px);
110
-
111
- display: block;
112
- /*padding: 8px;
113
- width: 100vw;
114
- height: 100vh;*/
115
- }
116
-
117
- :host([hideWeekend]) .grid-container {
118
- grid-template-columns: repeat(5, minmax(0, 1fr));
119
- }
120
-
121
- /* Layout Grid for the Calendar Component => Not really needed at the moment, more a test */
122
- .layout-container {
123
- width: var(--pd-calendar-width, 100%);
124
- min-width: 220px;
125
- height: 100%;
126
- display: grid;
127
- grid-template-columns: 1fr 1fr 1fr;
128
- grid-template-rows: 40px auto;
129
- gap: 1px;
130
- grid-template-areas:
131
- 'header header header'
132
- 'content content content';
133
- }
134
-
135
- /* Grid Area positions for layout container above */
136
- .header {
137
- grid-area: header;
138
- position: relative;
139
- font-family: var(--pd-default-font-title-family);
140
- color: var(--pd-default-font-title-col);
141
- display: flex;
142
- justify-content: left;
143
- }
144
-
145
- .header-main {
146
- display: flex;
147
- align-items: center;
148
- justify-content: space-between;
149
- width: 100%;
150
- }
151
-
152
- .content {
153
- grid-area: content;
154
- }
155
- .footer {
156
- grid-area: footer;
157
- }
158
-
159
- /* Grid definition for calendar day items */
160
- .grid-container {
161
- position: relative;
162
- display: grid;
163
- grid-template-columns: repeat(7, minmax(0, 1fr));
164
- gap: 3px;
165
- }
166
-
167
- .grid-container.max {
168
- grid-template-rows: minmax(10px, 30px) repeat(6, minmax(var(--my-cell-height), 1fr));
169
- }
170
-
171
- .grid-container.normal {
172
- grid-template-rows: minmax(10px, 30px) repeat(5, minmax(var(--my-cell-height), 1fr));
173
- }
174
-
175
- .title-week-day {
176
- display: flex;
177
- align-items: center;
178
- justify-content: center;
179
- background-color: var(--pd-calendar-week-title-bg-col, var(--pd-default-dark-col));
180
- font-size: var(--pd-calendar-weekday-title-font-size, 1em);
181
- font-weight: bold;
182
- color: var(--pd-calendar-week-title-font-col, var(--pd-default-bg-col));
183
- font-family: var(--pd-default-font-title-family);
184
- }
185
-
186
- .content-title {
187
- position: relative;
188
- font-size: var(--pd-calendar-title-font-size, 1.2em);
189
- font-weight: bold;
190
- }
191
-
192
- .icon-container {
193
- display: flex;
194
- align-items: center;
195
- justify-content: center;
196
- gap: 5px;
197
- }
198
-
199
- .arrow {
200
- cursor: pointer;
201
- --pd-icon-size: var(--pd-calendar-title-icon-size, 1.2em);
202
- --pd-icon-bg-col-hover: lightgrey;
203
- }
204
-
205
- .year-popup-link {
206
-
207
- }
208
-
209
- .year-popup-link:hover {
210
- cursor: pointer;
211
- color: var(--pd-default-hover-col);
212
- }
213
-
214
- `
215
- ];
216
- }
217
- constructor() {
218
- super();
219
- updateWhenLocaleChanges(this);
220
- this.data = {};
221
- this._viewType = VIEW_MONTH;
222
- this.numberClass = "top-left";
223
- this.hideWeekend = false;
224
- this.selectableDates = false;
225
- this.showSelection = false;
226
- this._wheelDelta = 0;
227
- this._currentMonthNavNr = 0;
228
- }
229
- connectedCallback() {
230
- super.connectedCallback();
231
- const ref = this.refDate || /* @__PURE__ */ new Date();
232
- this._initFromDate(ref);
233
- }
234
- update(changedProperties) {
235
- if (changedProperties.has("data") && this.data && this.data.monthSelection) {
236
- const now = new Date(Date.now());
237
- const startDateNextMonth = new Date(now.getFullYear(), this.data.monthSelection, 1);
238
- this._currentMonthNavNr += 1;
239
- this._initFromDate(startDateNextMonth);
240
- }
241
- if (changedProperties.has("refDate") && this.refDate) {
242
- this._initFromDate(this.refDate);
243
- }
244
- super.update(changedProperties);
245
- }
246
- render() {
247
- return html`
248
- ${this.renderCalendarByViewType()}
249
- <slot name="calFooter"></slot>
250
- `;
251
- }
252
- renderCalendarByViewType() {
253
- switch (this._viewType) {
254
- case VIEW_LIST:
255
- return "";
256
- case VIEW_MONTH:
257
- return this.renderMonthCalendar();
258
- case VIEW_WEEK:
259
- return this.renderCalendar();
260
- default:
261
- return this.renderMonthCalendar();
262
- }
263
- }
264
- /*
265
- renderListCalendar() {
266
- // TODO
267
- }
268
- */
269
- renderMonthCalendar() {
270
- const itemTemplates = [];
271
- const sizeVar = this._numberOfDays >= 31 && this._daysFromPreviousMonth.length >= 5 ? "max" : "normal";
272
- for (let i = 1; i <= this._numberOfDays; i += 1) {
273
- const tmpDate = new Date(this._year, this._currentDate.getMonth(), i);
274
- const day = tmpDate.getDay();
275
- if (!this.hideWeekend || day !== 6 && day !== 0) {
276
- const key = format(tmpDate, "YYYY-MM-DD");
277
- const infoTxt = this.data && this.data[key] ? this.data[key][0].info : void 0;
278
- const special = this.data && this.data[key] ? this.data[key][0].special || false : false;
279
- itemTemplates.push(html`
280
- <pd-calendar-cell
281
- key="${key}"
282
- dayNumber="${i}"
283
- weekDayNumber="${tmpDate.getDay()}"
284
- infoTxt="${infoTxt}"
285
- ?selectEnabled="${this.selectableDates || infoTxt !== void 0}"
286
- ?special="${special}"
287
- numberClass="${this.numberClass}"
288
- @select-date="${this._forwardEvent}"
289
- @mouse-enter-date="${this._forwardEnterEvent}"
290
- @mouse-leave-date="${this._forwardLeaveEvent}"
291
- ?today="${this.selectableDates && isToday(tmpDate)}"
292
- ?selected="${this.showSelection && isSelected(this.refDate, tmpDate)}"
293
- ></pd-calendar-cell>
294
- `);
295
- }
296
- }
297
- return html`
298
- <div class="layout-container">
299
- <div class="header">
300
-
301
- <div class="header-main">
302
-
303
- <div class="icon-container">
304
- <pd-icon
305
- @click="${this._previousMonth}"
306
- class="arrow"
307
- activeIcon
308
- icon="previousArrow"
309
- ></pd-icon>
310
-
311
- <pd-icon
312
- @click="${this._nextMonth}"
313
- class="arrow"
314
- activeIcon
315
- icon="nextArrow"
316
- ></pd-icon>
317
- </div>
318
-
319
- <div id="titleContentId" class="content-title">
320
- ${this._monthName} ${this.withYearPopup && this.withYearPopup.length > 0 ? html`
321
- <span class="year-popup-link" @click="${this._openYearPopup}">${this._year}</span>
322
- ` : html`${this._year}`}
323
- </div>
324
-
325
- </div>
326
-
327
- </div>
328
-
329
- <div
330
- @wheel="${this._wheelEvent}"
331
- @touchstart="${this._touchStartEvent}"
332
- @touchend="${this._touchEndEvent}"
333
- class="content grid-container ${sizeVar}">
334
- ${this._getWeekDays().map(
335
- (shortName) => html` <div class="title-week-day">${shortName}</div>`
336
- )}
337
- ${this._daysFromPreviousMonth.map(
338
- () => html` <div class="cell cell-empty"></div>`
339
- )}
340
- ${itemTemplates}
341
- </div>
342
- </div>
343
- `;
344
- }
345
- // eslint-disable-next-line class-methods-use-this
346
- _openYearPopup() {
347
- const popup = new PdYearPopup();
348
- popup.yearSelection = this.withYearPopup;
349
- this.shadowRoot.getElementById("titleContentId").appendChild(popup);
350
- popup.addEventListener("abort-year-selection", () => {
351
- this.shadowRoot.getElementById("titleContentId").removeChild(popup);
352
- });
353
- popup.addEventListener("change-year-selection", (e) => {
354
- const newYear = e.detail.year;
355
- if (newYear) {
356
- const newDate = new Date(
357
- this._currentDate.getFullYear(),
358
- this._currentDate.getMonth(),
359
- 1
360
- );
361
- newDate.setFullYear(newYear);
362
- this.dispatchEvent(
363
- new CustomEvent("change-month", {
364
- detail: {
365
- newDate
366
- }
367
- })
368
- );
369
- this._initFromDate(newDate);
370
- }
371
- this.shadowRoot.getElementById("titleContentId").removeChild(popup);
372
- });
373
- }
374
- // eslint-disable-next-line class-methods-use-this
375
- _getWeekDays() {
376
- return this.hideWeekend ? [
377
- ...LOCALES.weekdaysShort
378
- ].splice(0, 5) : LOCALES.weekdaysShort;
379
- }
380
- _nextMonth() {
381
- if (this._checkNextMonthConstraint()) {
382
- const newDate = new Date(
383
- this._currentDate.getFullYear(),
384
- this._currentDate.getMonth(),
385
- 1
386
- );
387
- newDate.setMonth(newDate.getMonth() + 1);
388
- this.dispatchEvent(
389
- new CustomEvent("change-month", {
390
- detail: {
391
- newDate,
392
- next: true
393
- }
394
- })
395
- );
396
- this._currentMonthNavNr += 1;
397
- this._initFromDate(newDate);
398
- }
399
- }
400
- _previousMonth() {
401
- if (this._checkPrevMonthConstraint()) {
402
- const newDate = new Date(
403
- this._currentDate.getFullYear(),
404
- this._currentDate.getMonth(),
405
- 1
406
- );
407
- newDate.setMonth(newDate.getMonth() - 1);
408
- this.dispatchEvent(
409
- new CustomEvent("change-month", {
410
- detail: {
411
- newDate,
412
- prev: true
413
- }
414
- })
415
- );
416
- this._currentMonthNavNr -= 1;
417
- this._initFromDate(newDate);
418
- }
419
- }
420
- // eslint-disable-next-line class-methods-use-this
421
- _wheelEvent(e) {
422
- if (this.withWheelNavigation) {
423
- this._wheelDelta += e.deltaY;
424
- if (this._wheelDelta > 360) {
425
- this._wheelDelta = 0;
426
- this._nextMonth();
427
- }
428
- if (this._wheelDelta < -360) {
429
- this._wheelDelta = 0;
430
- this._previousMonth();
431
- }
432
- }
433
- e.preventDefault();
434
- e.stopPropagation();
435
- }
436
- // eslint-disable-next-line class-methods-use-this
437
- _touchStartEvent(e) {
438
- if (this.withTouchNavigation) {
439
- this._wheelDelta = e.changedTouches[0].screenX;
440
- }
441
- e.stopPropagation();
442
- }
443
- _touchEndEvent(e) {
444
- if (this.withTouchNavigation) {
445
- const touchEndX = e.changedTouches[0].screenX;
446
- const result = this._wheelDelta - touchEndX;
447
- if (result < TOUCH_MIN_MOVE * -1) {
448
- this._nextMonth();
449
- } else if (result > TOUCH_MIN_MOVE) {
450
- this._previousMonth();
451
- }
452
- }
453
- e.stopPropagation();
454
- }
455
- _initFromDate(date) {
456
- this._monthName = date.toLocaleString("default", { month: "long" });
457
- this._year = date.getFullYear();
458
- this._daysFromPreviousMonth = PdCalendar._getPreviousMonthDays(date);
459
- const newDate2 = new Date(date.getFullYear(), date.getMonth() + 1, 0);
460
- this._numberOfDays = newDate2.getDate();
461
- this._currentDate = date;
462
- }
463
- static _getPreviousMonthDays(date) {
464
- const date1 = new Date(date.getFullYear(), date.getMonth(), 1);
465
- const missingDays = date1.getDay() > 0 ? Math.abs(1 - date1.getDay()) : 6;
466
- const missDayArray = [];
467
- for (let i = 1; i <= missingDays; i += 1) {
468
- date1.setDate(date1.getDate() - 1);
469
- missDayArray.push(
470
- new Date(date1.getFullYear(), date1.getMonth(), date1.getDate())
471
- );
472
- }
473
- return missDayArray;
474
- }
475
- _checkNextMonthConstraint() {
476
- if (this.nextMonthConstraint > 0) {
477
- return this.nextMonthConstraint > this._currentMonthNavNr;
478
- }
479
- if (this.nextMonthConstraint === -1) {
480
- return true;
481
- }
482
- return false;
483
- }
484
- _checkPrevMonthConstraint() {
485
- if (this._currentMonthNavNr > 0 || this.prevMonthConstraint === -1) {
486
- return true;
487
- }
488
- return this.prevMonthConstraint > this._currentMonthNavNr * -1;
489
- }
490
- // Forward Event from Calendar Cell, should be refactored (events not bubbles up here)
491
- _forwardEvent(e) {
492
- this.dispatchEvent(
493
- new CustomEvent("select-date", {
494
- detail: e.detail
495
- })
496
- );
497
- }
498
- _forwardEnterEvent(e) {
499
- this.dispatchEvent(
500
- new CustomEvent("mouse-enter-date", {
501
- detail: e.detail
502
- })
503
- );
504
- }
505
- _forwardLeaveEvent() {
506
- this.dispatchEvent(
507
- new CustomEvent("mouse-leave-date")
508
- );
509
- }
510
- }
511
- export {
512
- PdCalendar
513
- };