@cedx/base 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/Date.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Returns the date at midnight corresponding to the specified date.
3
+ * @param date The source date.
4
+ * @returns The date whose time has been set at midnight.
5
+ */
6
+ export declare function atMidnight(date: Date): Date;
7
+ /**
8
+ * Gets the number of days in the month of the specified date.
9
+ * @param date The date.
10
+ * @returns The number of days in the month of the specified date.
11
+ */
12
+ export declare function daysInMonth(date: Date): number;
13
+ /**
14
+ * Gets the date of Easter for a given year.
15
+ * @param year The year.
16
+ * @returns The date of Easter for the specified year.
17
+ */
18
+ export declare function getEaster(year?: number): Date;
19
+ /**
20
+ * Gets the list of holidays for a given year.
21
+ * @param year The year.
22
+ * @returns The list of holidays for the specified year.
23
+ */
24
+ export declare function getHolidays(year?: number): Date[];
25
+ /**
26
+ * Gets the quarter corresponding to the specified date.
27
+ * @param date The date.
28
+ * @returns The quarter corresponding to the specified date.
29
+ */
30
+ export declare function getQuarter(date: Date): number;
31
+ /**
32
+ * Gets the week number corresponding to the specified date.
33
+ * @param date The date.
34
+ * @returns The week number corresponding to the specified date.
35
+ */
36
+ export declare function getWeekOfYear(date: Date): number;
37
+ /**
38
+ * Returns a value indicating whether the specified date is in a leap year.
39
+ * @param date The date to check.
40
+ * @returns `true` if the specified date is in a leap year, otherwise `false`.
41
+ */
42
+ export declare function inLeapYear(date: Date): boolean;
43
+ /**
44
+ * Returns a value indicating whether the specified date is a holiday.
45
+ * @param date The date to check.
46
+ * @returns `true` if the specified date is a holiday, otherwise `false`.
47
+ */
48
+ export declare function isHoliday(date: Date): boolean;
49
+ /**
50
+ * Returns a value indicating whether the specified date is a working day.
51
+ * @param date The date to check.
52
+ * @returns `true` if the specified date is a working day, otherwise `false`.
53
+ */
54
+ export declare function isWorkingDay(date: Date): boolean;
55
+ /**
56
+ * Converts the specified date to an ISO 8601 week.
57
+ * @param date The date to convert.
58
+ * @returns The ISO 8601 week corresponding to the specified date.
59
+ */
60
+ export declare function toIsoWeek(date: Date): string;
61
+ /**
62
+ * Converts the specified date to the `YYYY-MM-DD HH:MM:SS` format.
63
+ * @param date The date to convert.
64
+ * @param options Values indicating how to format the resulting string.
65
+ * @returns The `YYYY-MM-DD HH:MM:SS` format corresponding to the specified date.
66
+ */
67
+ export declare function toYmdHms(date: Date, options?: {
68
+ excludeDate?: boolean;
69
+ excludeTime?: boolean;
70
+ separator?: string;
71
+ }): string;
72
+ //# sourceMappingURL=Date.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Date.d.ts","sourceRoot":"","sources":["../src/Client/Date.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,SAA2B,GAAG,IAAI,CAY/D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,SAA2B,GAAG,IAAI,EAAE,CAoBnE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAG7C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAGhD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAM,GAAG,MAAM,CAM7H"}
package/lib/Date.js ADDED
@@ -0,0 +1,125 @@
1
+ import { Duration } from "./Duration.js";
2
+ /**
3
+ * Returns the date at midnight corresponding to the specified date.
4
+ * @param date The source date.
5
+ * @returns The date whose time has been set at midnight.
6
+ */
7
+ export function atMidnight(date) {
8
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
9
+ }
10
+ /**
11
+ * Gets the number of days in the month of the specified date.
12
+ * @param date The date.
13
+ * @returns The number of days in the month of the specified date.
14
+ */
15
+ export function daysInMonth(date) {
16
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
17
+ }
18
+ /**
19
+ * Gets the date of Easter for a given year.
20
+ * @param year The year.
21
+ * @returns The date of Easter for the specified year.
22
+ */
23
+ export function getEaster(year = new Date().getFullYear()) {
24
+ /* eslint-disable id-length */
25
+ const n = year % 19;
26
+ const c = Math.trunc(year / 100);
27
+ const u = year % 100;
28
+ const e = ((19 * n) + c - Math.trunc(c / 4) - Math.trunc((c - Math.trunc((c + 8) / 25) + 1) / 3) + 15) % 30;
29
+ const l = ((2 * (c % 4)) + (2 * Math.trunc(u / 4)) - e - (u % 4) + 32) % 7;
30
+ const h = Math.trunc((n + (11 * e) + (22 * l)) / 451);
31
+ const result = e + l - (7 * h) + 114;
32
+ /* eslint-enable id-length */
33
+ return new Date(year, Math.trunc(result / 31) - 1, (result % 31) + 1);
34
+ }
35
+ /**
36
+ * Gets the list of holidays for a given year.
37
+ * @param year The year.
38
+ * @returns The list of holidays for the specified year.
39
+ */
40
+ export function getHolidays(year = new Date().getFullYear()) {
41
+ const holidays = [];
42
+ // Fixed holidays.
43
+ holidays.push(new Date(year, 0, 1)); // New year.
44
+ holidays.push(new Date(year, 4, 1)); // Labor day.
45
+ holidays.push(new Date(year, 4, 8)); // Armistice (1945).
46
+ holidays.push(new Date(year, 6, 14)); // National holiday.
47
+ holidays.push(new Date(year, 7, 15)); // Assumption.
48
+ holidays.push(new Date(year, 10, 1)); // Toussaint.
49
+ holidays.push(new Date(year, 10, 11)); // Armistice (1918).
50
+ holidays.push(new Date(year, 11, 25)); // Christmas.
51
+ // Holidays depending on Easter.
52
+ const easter = getEaster(year);
53
+ holidays.push(new Date(easter.getTime() + Duration.Day)); // Easter monday.
54
+ holidays.push(new Date(easter.getTime() + (39 * Duration.Day))); // Ascension thursday.
55
+ holidays.push(new Date(easter.getTime() + (50 * Duration.Day))); // Pentecost monday.
56
+ return holidays;
57
+ }
58
+ /**
59
+ * Gets the quarter corresponding to the specified date.
60
+ * @param date The date.
61
+ * @returns The quarter corresponding to the specified date.
62
+ */
63
+ export function getQuarter(date) {
64
+ return Math.ceil((date.getMonth() + 1) / 3);
65
+ }
66
+ /**
67
+ * Gets the week number corresponding to the specified date.
68
+ * @param date The date.
69
+ * @returns The week number corresponding to the specified date.
70
+ */
71
+ export function getWeekOfYear(date) {
72
+ const thursday = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 3 - ((date.getDay() + 6) % 7));
73
+ const firstWeek = new Date(thursday.getFullYear(), 0, 4);
74
+ return 1 + Math.round((((thursday.getTime() - firstWeek.getTime()) / Duration.Day) - 3 + ((firstWeek.getDay() + 6) % 7)) / 7);
75
+ }
76
+ /**
77
+ * Returns a value indicating whether the specified date is in a leap year.
78
+ * @param date The date to check.
79
+ * @returns `true` if the specified date is in a leap year, otherwise `false`.
80
+ */
81
+ export function inLeapYear(date) {
82
+ const year = date.getFullYear();
83
+ return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
84
+ }
85
+ /**
86
+ * Returns a value indicating whether the specified date is a holiday.
87
+ * @param date The date to check.
88
+ * @returns `true` if the specified date is a holiday, otherwise `false`.
89
+ */
90
+ export function isHoliday(date) {
91
+ const timestamp = atMidnight(date).getTime();
92
+ return getHolidays(date.getFullYear()).some(holiday => holiday.getTime() == timestamp);
93
+ }
94
+ /**
95
+ * Returns a value indicating whether the specified date is a working day.
96
+ * @param date The date to check.
97
+ * @returns `true` if the specified date is a working day, otherwise `false`.
98
+ */
99
+ export function isWorkingDay(date) {
100
+ const dayOfWeek = date.getDay();
101
+ return dayOfWeek >= 1 && dayOfWeek <= 5;
102
+ }
103
+ /**
104
+ * Converts the specified date to an ISO 8601 week.
105
+ * @param date The date to convert.
106
+ * @returns The ISO 8601 week corresponding to the specified date.
107
+ */
108
+ export function toIsoWeek(date) {
109
+ return `${date.getFullYear().toString().padStart(4, "0")}-W${getWeekOfYear(date).toString().padStart(2, "0")}`;
110
+ }
111
+ /**
112
+ * Converts the specified date to the `YYYY-MM-DD HH:MM:SS` format.
113
+ * @param date The date to convert.
114
+ * @param options Values indicating how to format the resulting string.
115
+ * @returns The `YYYY-MM-DD HH:MM:SS` format corresponding to the specified date.
116
+ */
117
+ export function toYmdHms(date, options = {}) {
118
+ const padStart = (number, length = 2) => number.toString().padStart(length, "0");
119
+ const parts = [];
120
+ if (!options.excludeDate)
121
+ parts.push([padStart(date.getFullYear(), 4), padStart(date.getMonth() + 1), padStart(date.getDate())].join("-"));
122
+ if (!options.excludeTime)
123
+ parts.push([date.getHours(), date.getMinutes(), date.getSeconds()].map(item => padStart(item)).join(":"));
124
+ return parts.join(options.separator ?? " ");
125
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Provides some common durations in milliseconds.
3
+ */
4
+ export declare const Duration: Readonly<{
5
+ /**
6
+ * One second.
7
+ */
8
+ Second: 1000;
9
+ /**
10
+ * One minute.
11
+ */
12
+ Minute: 60000;
13
+ /**
14
+ * One hour.
15
+ */
16
+ Hour: 3600000;
17
+ /**
18
+ * One day.
19
+ */
20
+ Day: 86400000;
21
+ }>;
22
+ /**
23
+ * Provides some common durations in milliseconds.
24
+ */
25
+ export type Duration = typeof Duration[keyof typeof Duration];
26
+ //# sourceMappingURL=Duration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Duration.d.ts","sourceRoot":"","sources":["../src/Client/Duration.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ;IAEpB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Provides some common durations in milliseconds.
3
+ */
4
+ export const Duration = Object.freeze({
5
+ /**
6
+ * One second.
7
+ */
8
+ Second: 1_000,
9
+ /**
10
+ * One minute.
11
+ */
12
+ Minute: 60_000,
13
+ /**
14
+ * One hour.
15
+ */
16
+ Hour: 3_600_000,
17
+ /**
18
+ * One day.
19
+ */
20
+ Day: 86_400_000
21
+ });
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Defines contextual modifiers.
3
+ */
4
+ export declare const Context: Readonly<{
5
+ /**
6
+ * A danger.
7
+ */
8
+ Danger: "danger";
9
+ /**
10
+ * A warning.
11
+ */
12
+ Warning: "warning";
13
+ /**
14
+ * An information.
15
+ */
16
+ Info: "info";
17
+ /**
18
+ * A success.
19
+ */
20
+ Success: "success";
21
+ }>;
22
+ /**
23
+ * Defines contextual modifiers.
24
+ */
25
+ export type Context = typeof Context[keyof typeof Context];
26
+ /**
27
+ * Gets the icon corresponding to the specified context.
28
+ * @param context The context.
29
+ * @returns The icon corresponding to the specified context.
30
+ */
31
+ export declare function contextIcon(context: Context): string;
32
+ //# sourceMappingURL=Context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Context.d.ts","sourceRoot":"","sources":["../../src/Client/Html/Context.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO;IAEnB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAOpD"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Defines contextual modifiers.
3
+ */
4
+ export const Context = Object.freeze({
5
+ /**
6
+ * A danger.
7
+ */
8
+ Danger: "danger",
9
+ /**
10
+ * A warning.
11
+ */
12
+ Warning: "warning",
13
+ /**
14
+ * An information.
15
+ */
16
+ Info: "info",
17
+ /**
18
+ * A success.
19
+ */
20
+ Success: "success"
21
+ });
22
+ /**
23
+ * Gets the icon corresponding to the specified context.
24
+ * @param context The context.
25
+ * @returns The icon corresponding to the specified context.
26
+ */
27
+ export function contextIcon(context) {
28
+ switch (context) {
29
+ case Context.Danger: return "error";
30
+ case Context.Success: return "check_circle";
31
+ case Context.Warning: return "warning";
32
+ default: return "info";
33
+ }
34
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Downloads the specified file.
3
+ * @param file The file to be downloaded.
4
+ */
5
+ export declare function downloadFile(file: File): void;
6
+ /**
7
+ * Downloads the specified text content.
8
+ * @param text The text content.
9
+ * @param fileName The file name.
10
+ * @param options The optional attributes for the file.
11
+ */
12
+ export declare function downloadString(text: string, fileName: string, options?: FilePropertyBag): void;
13
+ /**
14
+ * Opens the specified file.
15
+ * @param file The file to be opened.
16
+ * @param options Value indicating whether to open the file in a new tab.
17
+ */
18
+ export declare function openFile(file: File, options?: {
19
+ newTab?: boolean;
20
+ }): void;
21
+ /**
22
+ * Prints the specified file.
23
+ * @param file The file to be printed.
24
+ */
25
+ export declare function printFile(file: File): void;
26
+ /**
27
+ * Converts the specified file to a data URL.
28
+ * @param file The file to convert.
29
+ * @returns The data URL corresponding to the given file.
30
+ */
31
+ export declare function toDataUrl(file: File): Promise<URL>;
32
+ //# sourceMappingURL=File.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"File.d.ts","sourceRoot":"","sources":["../../src/Client/Html/File.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAU7C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,IAAI,CAElG;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAM,GAAG,IAAI,CAkB3E;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAa1C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAOlD"}
@@ -0,0 +1,76 @@
1
+ import { Duration } from "#Base/Duration.js";
2
+ /**
3
+ * Downloads the specified file.
4
+ * @param file The file to be downloaded.
5
+ */
6
+ export function downloadFile(file) {
7
+ const url = URL.createObjectURL(file);
8
+ const anchor = document.createElement("a");
9
+ anchor.download = file.name;
10
+ anchor.href = url;
11
+ document.body.appendChild(anchor);
12
+ anchor.click();
13
+ document.body.removeChild(anchor);
14
+ URL.revokeObjectURL(url);
15
+ }
16
+ /**
17
+ * Downloads the specified text content.
18
+ * @param text The text content.
19
+ * @param fileName The file name.
20
+ * @param options The optional attributes for the file.
21
+ */
22
+ export function downloadString(text, fileName, options = {}) {
23
+ downloadFile(new File([text], fileName, options));
24
+ }
25
+ /**
26
+ * Opens the specified file.
27
+ * @param file The file to be opened.
28
+ * @param options Value indicating whether to open the file in a new tab.
29
+ */
30
+ export function openFile(file, options = {}) {
31
+ const url = URL.createObjectURL(file);
32
+ if (!options.newTab) {
33
+ location.assign(url);
34
+ return;
35
+ }
36
+ const handle = window.open(url, "_blank");
37
+ if (!handle) {
38
+ location.assign(url);
39
+ return;
40
+ }
41
+ const timer = window.setInterval(() => {
42
+ if (!handle.closed)
43
+ return;
44
+ clearInterval(timer);
45
+ URL.revokeObjectURL(url);
46
+ }, 5 * Duration.Second);
47
+ }
48
+ /**
49
+ * Prints the specified file.
50
+ * @param file The file to be printed.
51
+ */
52
+ export function printFile(file) {
53
+ const url = URL.createObjectURL(file);
54
+ const frame = document.createElement("iframe");
55
+ frame.addEventListener("load", () => frame.contentWindow?.print());
56
+ frame.hidden = true;
57
+ frame.src = url;
58
+ window.addEventListener("focus", () => {
59
+ document.body.removeChild(frame);
60
+ URL.revokeObjectURL(url);
61
+ }, { once: true });
62
+ document.body.appendChild(frame);
63
+ }
64
+ /**
65
+ * Converts the specified file to a data URL.
66
+ * @param file The file to convert.
67
+ * @returns The data URL corresponding to the given file.
68
+ */
69
+ export function toDataUrl(file) {
70
+ return new Promise((resolve, reject) => {
71
+ const reader = new FileReader;
72
+ reader.addEventListener("error", reject);
73
+ reader.addEventListener("load", () => resolve(new URL(reader.result)));
74
+ reader.readAsDataURL(file);
75
+ });
76
+ }
@@ -1,9 +1,8 @@
1
1
  import type { ILoadingIndicator } from "#Abstractions/ILoadingIndicator.js";
2
- import { LitElement, type TemplateResult } from "lit";
3
2
  /**
4
3
  * A component that shows up when an HTTP request starts, and hides when all concurrent HTTP requests are completed.
5
4
  */
6
- export declare class LoadingIndicator extends LitElement implements ILoadingIndicator {
5
+ export declare class LoadingIndicator extends HTMLElement implements ILoadingIndicator {
7
6
  #private;
8
7
  /**
9
8
  * Creates a new loading indicator.
@@ -20,11 +19,6 @@ export declare class LoadingIndicator extends LitElement implements ILoadingIndi
20
19
  stop(options?: {
21
20
  force?: boolean;
22
21
  }): void;
23
- /**
24
- * Renders this component.
25
- * @returns The view template.
26
- */
27
- protected render(): TemplateResult;
28
22
  }
29
23
  /**
30
24
  * Declaration merging.
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../../src/Client/UI/LoadingIndicator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAO,UAAU,EAAE,KAAK,cAAc,EAAC,MAAM,KAAK,CAAC;AAG1D;;GAEG;AACH,qBACa,gBAAiB,SAAQ,UAAW,YAAW,iBAAiB;;IAO5E;;OAEG;;IAMH;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;;OAGG;IACH,IAAI,CAAC,OAAO,GAAE;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,IAAI;IAS3C;;;OAGG;cACgB,MAAM,IAAI,cAAc;CAG3C;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,gBAAgB,CAAC;KACtC;CACD"}
1
+ {"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../../src/Client/UI/LoadingIndicator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,oCAAoC,CAAC;AAE1E;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAY,YAAW,iBAAiB;;IAO7E;;OAEG;;IAcH;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;;OAGG;IACH,IAAI,CAAC,OAAO,GAAE;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAM,GAAG,IAAI;CAQ3C;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,gBAAgB,CAAC;KACtC;CACD"}
@@ -1,10 +1,7 @@
1
- import { __decorate } from "tslib";
2
- import { html, LitElement } from "lit";
3
- import { customElement } from "lit/decorators.js";
4
1
  /**
5
2
  * A component that shows up when an HTTP request starts, and hides when all concurrent HTTP requests are completed.
6
3
  */
7
- let LoadingIndicator = class LoadingIndicator extends LitElement {
4
+ export class LoadingIndicator extends HTMLElement {
8
5
  /**
9
6
  * The number of concurrent HTTP requests.
10
7
  */
@@ -15,6 +12,13 @@ let LoadingIndicator = class LoadingIndicator extends LitElement {
15
12
  constructor() {
16
13
  super();
17
14
  this.hidden = true;
15
+ this.attachShadow({ mode: "open" }).appendChild(document.createElement("slot"));
16
+ }
17
+ /**
18
+ * Registers the component.
19
+ */
20
+ static {
21
+ customElements.define("loading-indicator", this);
18
22
  }
19
23
  /**
20
24
  * Starts the loading indicator.
@@ -36,15 +40,4 @@ let LoadingIndicator = class LoadingIndicator extends LitElement {
36
40
  document.body.classList.remove("loading");
37
41
  }
38
42
  }
39
- /**
40
- * Renders this component.
41
- * @returns The view template.
42
- */
43
- render() {
44
- return html `<slot></slot>`;
45
- }
46
- };
47
- LoadingIndicator = __decorate([
48
- customElement("loading-indicator")
49
- ], LoadingIndicator);
50
- export { LoadingIndicator };
43
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A component that activates the items of a menu based on the current document URL.
3
+ */
4
+ export declare class MenuActivator extends HTMLElement {
5
+ /**
6
+ * Creates a new menu activator.
7
+ */
8
+ constructor();
9
+ /**
10
+ * Method invoked when this component is connected.
11
+ */
12
+ connectedCallback(): void;
13
+ }
14
+ /**
15
+ * Declaration merging.
16
+ */
17
+ declare global {
18
+ /**
19
+ * The map of HTML tag names.
20
+ */
21
+ interface HTMLElementTagNameMap {
22
+ "menu-activator": MenuActivator;
23
+ }
24
+ }
25
+ //# sourceMappingURL=MenuActivator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MenuActivator.d.ts","sourceRoot":"","sources":["../../src/Client/UI/MenuActivator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAE7C;;OAEG;;IAaH;;OAEG;IACH,iBAAiB,IAAI,IAAI;CASzB;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,gBAAgB,EAAE,aAAa,CAAC;KAChC;CACD"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A component that activates the items of a menu based on the current document URL.
3
+ */
4
+ export class MenuActivator extends HTMLElement {
5
+ /**
6
+ * Creates a new menu activator.
7
+ */
8
+ constructor() {
9
+ super();
10
+ this.attachShadow({ mode: "open" }).appendChild(document.createElement("slot"));
11
+ }
12
+ /**
13
+ * Registers the component.
14
+ */
15
+ static {
16
+ customElements.define("menu-activator", this);
17
+ }
18
+ /**
19
+ * Method invoked when this component is connected.
20
+ */
21
+ connectedCallback() {
22
+ const menu = this.shadowRoot.querySelector("slot").assignedElements().at(0);
23
+ if (menu)
24
+ for (const anchor of menu.getElementsByTagName("a"))
25
+ if (anchor.href != location.href)
26
+ anchor.classList.remove("active");
27
+ else {
28
+ anchor.classList.add("active");
29
+ anchor.closest(".nav-item.dropdown")?.querySelector(".nav-link")?.classList.add("active");
30
+ }
31
+ }
32
+ }
@@ -1,8 +1,7 @@
1
- import { LitElement, type TemplateResult } from "lit";
2
1
  /**
3
2
  * A component that shows up when the network is unavailable, and hides when connectivity is restored.
4
3
  */
5
- export declare class OfflineIndicator extends LitElement {
4
+ export declare class OfflineIndicator extends HTMLElement {
6
5
  /**
7
6
  * Creates a new offline indicator.
8
7
  */
@@ -19,11 +18,6 @@ export declare class OfflineIndicator extends LitElement {
19
18
  * Handles the events.
20
19
  */
21
20
  handleEvent(): void;
22
- /**
23
- * Renders this component.
24
- * @returns The view template.
25
- */
26
- protected render(): TemplateResult;
27
21
  }
28
22
  /**
29
23
  * Declaration merging.
@@ -1 +1 @@
1
- {"version":3,"file":"OfflineIndicator.d.ts","sourceRoot":"","sources":["../../src/Client/UI/OfflineIndicator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,UAAU,EAAE,KAAK,cAAc,EAAC,MAAM,KAAK,CAAC;AAG1D;;GAEG;AACH,qBACa,gBAAiB,SAAQ,UAAU;IAE/C;;OAEG;;IAMH;;OAEG;IACM,iBAAiB,IAAI,IAAI;IAKlC;;OAEG;IACM,oBAAoB,IAAI,IAAI;IAKrC;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;;OAGG;cACgB,MAAM,IAAI,cAAc;CAG3C;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,gBAAgB,CAAC;KACtC;CACD"}
1
+ {"version":3,"file":"OfflineIndicator.d.ts","sourceRoot":"","sources":["../../src/Client/UI/OfflineIndicator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;IAEhD;;OAEG;;IAcH;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAI5B;;OAEG;IACH,WAAW,IAAI,IAAI;CAGnB;AAED;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,gBAAgB,CAAC;KACtC;CACD"}
@@ -1,22 +1,25 @@
1
- import { __decorate } from "tslib";
2
- import { html, LitElement } from "lit";
3
- import { customElement } from "lit/decorators.js";
4
1
  /**
5
2
  * A component that shows up when the network is unavailable, and hides when connectivity is restored.
6
3
  */
7
- let OfflineIndicator = class OfflineIndicator extends LitElement {
4
+ export class OfflineIndicator extends HTMLElement {
8
5
  /**
9
6
  * Creates a new offline indicator.
10
7
  */
11
8
  constructor() {
12
9
  super();
13
10
  this.hidden = navigator.onLine;
11
+ this.attachShadow({ mode: "open" }).appendChild(document.createElement("slot"));
12
+ }
13
+ /**
14
+ * Registers the component.
15
+ */
16
+ static {
17
+ customElements.define("offline-indicator", this);
14
18
  }
15
19
  /**
16
20
  * Method invoked when this component is connected.
17
21
  */
18
22
  connectedCallback() {
19
- super.connectedCallback();
20
23
  for (const event of ["online", "offline"])
21
24
  addEventListener(event, this);
22
25
  }
@@ -26,7 +29,6 @@ let OfflineIndicator = class OfflineIndicator extends LitElement {
26
29
  disconnectedCallback() {
27
30
  for (const event of ["online", "offline"])
28
31
  removeEventListener(event, this);
29
- super.disconnectedCallback();
30
32
  }
31
33
  /**
32
34
  * Handles the events.
@@ -34,15 +36,4 @@ let OfflineIndicator = class OfflineIndicator extends LitElement {
34
36
  handleEvent() {
35
37
  this.hidden = navigator.onLine;
36
38
  }
37
- /**
38
- * Renders this component.
39
- * @returns The view template.
40
- */
41
- render() {
42
- return html `<slot></slot>`;
43
- }
44
- };
45
- OfflineIndicator = __decorate([
46
- customElement("offline-indicator")
47
- ], OfflineIndicator);
48
- export { OfflineIndicator };
39
+ }
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "name": "@cedx/base",
8
8
  "repository": "cedx/base",
9
9
  "type": "module",
10
- "version": "0.1.0",
10
+ "version": "0.2.0",
11
11
  "devDependencies": {
12
12
  "@playwright/browser-chromium": "^1.54.2",
13
13
  "@types/bootstrap": "^5.2.10",
@@ -40,6 +40,7 @@
40
40
  ],
41
41
  "imports": {
42
42
  "#Abstractions/*.js": "./lib/Abstractions/*.js",
43
+ "#Base/*.js": "./lib/*.js",
43
44
  "#Html/*.js": "./lib/Html/*.js"
44
45
  },
45
46
  "keywords": [
@@ -0,0 +1,138 @@
1
+ import {Duration} from "./Duration.js";
2
+
3
+ /**
4
+ * Returns the date at midnight corresponding to the specified date.
5
+ * @param date The source date.
6
+ * @returns The date whose time has been set at midnight.
7
+ */
8
+ export function atMidnight(date: Date): Date {
9
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
10
+ }
11
+
12
+ /**
13
+ * Gets the number of days in the month of the specified date.
14
+ * @param date The date.
15
+ * @returns The number of days in the month of the specified date.
16
+ */
17
+ export function daysInMonth(date: Date): number {
18
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
19
+ }
20
+
21
+ /**
22
+ * Gets the date of Easter for a given year.
23
+ * @param year The year.
24
+ * @returns The date of Easter for the specified year.
25
+ */
26
+ export function getEaster(year = new Date().getFullYear()): Date {
27
+ /* eslint-disable id-length */
28
+ const n = year % 19;
29
+ const c = Math.trunc(year / 100);
30
+ const u = year % 100;
31
+ const e = ((19 * n) + c - Math.trunc(c / 4) - Math.trunc((c - Math.trunc((c + 8) / 25) + 1) / 3) + 15) % 30;
32
+ const l = ((2 * (c % 4)) + (2 * Math.trunc(u / 4)) - e - (u % 4) + 32) % 7;
33
+ const h = Math.trunc((n + (11 * e) + (22 * l)) / 451);
34
+ const result = e + l - (7 * h) + 114;
35
+ /* eslint-enable id-length */
36
+
37
+ return new Date(year, Math.trunc(result / 31) - 1, (result % 31) + 1);
38
+ }
39
+
40
+ /**
41
+ * Gets the list of holidays for a given year.
42
+ * @param year The year.
43
+ * @returns The list of holidays for the specified year.
44
+ */
45
+ export function getHolidays(year = new Date().getFullYear()): Date[] {
46
+ const holidays = [];
47
+
48
+ // Fixed holidays.
49
+ holidays.push(new Date(year, 0, 1)); // New year.
50
+ holidays.push(new Date(year, 4, 1)); // Labor day.
51
+ holidays.push(new Date(year, 4, 8)); // Armistice (1945).
52
+ holidays.push(new Date(year, 6, 14)); // National holiday.
53
+ holidays.push(new Date(year, 7, 15)); // Assumption.
54
+ holidays.push(new Date(year, 10, 1)); // Toussaint.
55
+ holidays.push(new Date(year, 10, 11)); // Armistice (1918).
56
+ holidays.push(new Date(year, 11, 25)); // Christmas.
57
+
58
+ // Holidays depending on Easter.
59
+ const easter = getEaster(year);
60
+ holidays.push(new Date(easter.getTime() + Duration.Day)); // Easter monday.
61
+ holidays.push(new Date(easter.getTime() + (39 * Duration.Day))); // Ascension thursday.
62
+ holidays.push(new Date(easter.getTime() + (50 * Duration.Day))); // Pentecost monday.
63
+
64
+ return holidays;
65
+ }
66
+
67
+ /**
68
+ * Gets the quarter corresponding to the specified date.
69
+ * @param date The date.
70
+ * @returns The quarter corresponding to the specified date.
71
+ */
72
+ export function getQuarter(date: Date): number {
73
+ return Math.ceil((date.getMonth() + 1) / 3);
74
+ }
75
+
76
+ /**
77
+ * Gets the week number corresponding to the specified date.
78
+ * @param date The date.
79
+ * @returns The week number corresponding to the specified date.
80
+ */
81
+ export function getWeekOfYear(date: Date): number {
82
+ const thursday = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 3 - ((date.getDay() + 6) % 7));
83
+ const firstWeek = new Date(thursday.getFullYear(), 0, 4);
84
+ return 1 + Math.round((((thursday.getTime() - firstWeek.getTime()) / Duration.Day) - 3 + ((firstWeek.getDay() + 6) % 7)) / 7);
85
+ }
86
+
87
+ /**
88
+ * Returns a value indicating whether the specified date is in a leap year.
89
+ * @param date The date to check.
90
+ * @returns `true` if the specified date is in a leap year, otherwise `false`.
91
+ */
92
+ export function inLeapYear(date: Date): boolean {
93
+ const year = date.getFullYear();
94
+ return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
95
+ }
96
+
97
+ /**
98
+ * Returns a value indicating whether the specified date is a holiday.
99
+ * @param date The date to check.
100
+ * @returns `true` if the specified date is a holiday, otherwise `false`.
101
+ */
102
+ export function isHoliday(date: Date): boolean {
103
+ const timestamp = atMidnight(date).getTime();
104
+ return getHolidays(date.getFullYear()).some(holiday => holiday.getTime() == timestamp);
105
+ }
106
+
107
+ /**
108
+ * Returns a value indicating whether the specified date is a working day.
109
+ * @param date The date to check.
110
+ * @returns `true` if the specified date is a working day, otherwise `false`.
111
+ */
112
+ export function isWorkingDay(date: Date): boolean {
113
+ const dayOfWeek = date.getDay();
114
+ return dayOfWeek >= 1 && dayOfWeek <= 5;
115
+ }
116
+
117
+ /**
118
+ * Converts the specified date to an ISO 8601 week.
119
+ * @param date The date to convert.
120
+ * @returns The ISO 8601 week corresponding to the specified date.
121
+ */
122
+ export function toIsoWeek(date: Date): string {
123
+ return `${date.getFullYear().toString().padStart(4, "0")}-W${getWeekOfYear(date).toString().padStart(2, "0")}`;
124
+ }
125
+
126
+ /**
127
+ * Converts the specified date to the `YYYY-MM-DD HH:MM:SS` format.
128
+ * @param date The date to convert.
129
+ * @param options Values indicating how to format the resulting string.
130
+ * @returns The `YYYY-MM-DD HH:MM:SS` format corresponding to the specified date.
131
+ */
132
+ export function toYmdHms(date: Date, options: {excludeDate?: boolean, excludeTime?: boolean, separator?: string} = {}): string {
133
+ const padStart = (number: number, length = 2): string => number.toString().padStart(length, "0");
134
+ const parts = [];
135
+ if (!options.excludeDate) parts.push([padStart(date.getFullYear(), 4), padStart(date.getMonth() + 1), padStart(date.getDate())].join("-"));
136
+ if (!options.excludeTime) parts.push([date.getHours(), date.getMinutes(), date.getSeconds()].map(item => padStart(item)).join(":"));
137
+ return parts.join(options.separator ?? " ");
138
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Provides some common durations in milliseconds.
3
+ */
4
+ export const Duration = Object.freeze({
5
+
6
+ /**
7
+ * One second.
8
+ */
9
+ Second: 1_000,
10
+
11
+ /**
12
+ * One minute.
13
+ */
14
+ Minute: 60_000,
15
+
16
+ /**
17
+ * One hour.
18
+ */
19
+ Hour: 3_600_000,
20
+
21
+ /**
22
+ * One day.
23
+ */
24
+ Day: 86_400_000
25
+ });
26
+
27
+ /**
28
+ * Provides some common durations in milliseconds.
29
+ */
30
+ export type Duration = typeof Duration[keyof typeof Duration];
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Defines contextual modifiers.
3
+ */
4
+ export const Context = Object.freeze({
5
+
6
+ /**
7
+ * A danger.
8
+ */
9
+ Danger: "danger",
10
+
11
+ /**
12
+ * A warning.
13
+ */
14
+ Warning: "warning",
15
+
16
+ /**
17
+ * An information.
18
+ */
19
+ Info: "info",
20
+
21
+ /**
22
+ * A success.
23
+ */
24
+ Success: "success"
25
+ });
26
+
27
+ /**
28
+ * Defines contextual modifiers.
29
+ */
30
+ export type Context = typeof Context[keyof typeof Context];
31
+
32
+ /**
33
+ * Gets the icon corresponding to the specified context.
34
+ * @param context The context.
35
+ * @returns The icon corresponding to the specified context.
36
+ */
37
+ export function contextIcon(context: Context): string {
38
+ switch (context) {
39
+ case Context.Danger: return "error";
40
+ case Context.Success: return "check_circle";
41
+ case Context.Warning: return "warning";
42
+ default: return "info";
43
+ }
44
+ }
@@ -0,0 +1,85 @@
1
+ import {Duration} from "#Base/Duration.js";
2
+
3
+ /**
4
+ * Downloads the specified file.
5
+ * @param file The file to be downloaded.
6
+ */
7
+ export function downloadFile(file: File): void {
8
+ const url = URL.createObjectURL(file);
9
+ const anchor = document.createElement("a");
10
+ anchor.download = file.name;
11
+ anchor.href = url;
12
+
13
+ document.body.appendChild(anchor);
14
+ anchor.click();
15
+ document.body.removeChild(anchor);
16
+ URL.revokeObjectURL(url);
17
+ }
18
+
19
+ /**
20
+ * Downloads the specified text content.
21
+ * @param text The text content.
22
+ * @param fileName The file name.
23
+ * @param options The optional attributes for the file.
24
+ */
25
+ export function downloadString(text: string, fileName: string, options: FilePropertyBag = {}): void {
26
+ downloadFile(new File([text], fileName, options));
27
+ }
28
+
29
+ /**
30
+ * Opens the specified file.
31
+ * @param file The file to be opened.
32
+ * @param options Value indicating whether to open the file in a new tab.
33
+ */
34
+ export function openFile(file: File, options: {newTab?: boolean} = {}): void {
35
+ const url = URL.createObjectURL(file);
36
+ if (!options.newTab) {
37
+ location.assign(url);
38
+ return;
39
+ }
40
+
41
+ const handle = window.open(url, "_blank");
42
+ if (!handle) {
43
+ location.assign(url);
44
+ return;
45
+ }
46
+
47
+ const timer = window.setInterval(() => {
48
+ if (!handle.closed) return;
49
+ clearInterval(timer);
50
+ URL.revokeObjectURL(url);
51
+ }, 5 * Duration.Second);
52
+ }
53
+
54
+ /**
55
+ * Prints the specified file.
56
+ * @param file The file to be printed.
57
+ */
58
+ export function printFile(file: File): void {
59
+ const url = URL.createObjectURL(file);
60
+ const frame = document.createElement("iframe");
61
+ frame.addEventListener("load", () => frame.contentWindow?.print());
62
+ frame.hidden = true;
63
+ frame.src = url;
64
+
65
+ window.addEventListener("focus", () => {
66
+ document.body.removeChild(frame);
67
+ URL.revokeObjectURL(url);
68
+ }, {once: true});
69
+
70
+ document.body.appendChild(frame);
71
+ }
72
+
73
+ /**
74
+ * Converts the specified file to a data URL.
75
+ * @param file The file to convert.
76
+ * @returns The data URL corresponding to the given file.
77
+ */
78
+ export function toDataUrl(file: File): Promise<URL> {
79
+ return new Promise((resolve, reject) => {
80
+ const reader = new FileReader;
81
+ reader.addEventListener("error", reject);
82
+ reader.addEventListener("load", () => resolve(new URL(reader.result as string)));
83
+ reader.readAsDataURL(file);
84
+ });
85
+ }
@@ -9,5 +9,8 @@
9
9
  "outDir": "../../../lib/Html",
10
10
  "rootDir": ".",
11
11
  "tsBuildInfoFile": "../../../var/Html.tsbuildinfo"
12
- }
12
+ },
13
+ "references": [
14
+ {"path": "../Base/tsconfig.json"}
15
+ ]
13
16
  }
@@ -1,12 +1,9 @@
1
1
  import type {ILoadingIndicator} from "#Abstractions/ILoadingIndicator.js";
2
- import {html, LitElement, type TemplateResult} from "lit";
3
- import {customElement} from "lit/decorators.js";
4
2
 
5
3
  /**
6
4
  * A component that shows up when an HTTP request starts, and hides when all concurrent HTTP requests are completed.
7
5
  */
8
- @customElement("loading-indicator")
9
- export class LoadingIndicator extends LitElement implements ILoadingIndicator {
6
+ export class LoadingIndicator extends HTMLElement implements ILoadingIndicator {
10
7
 
11
8
  /**
12
9
  * The number of concurrent HTTP requests.
@@ -19,6 +16,14 @@ export class LoadingIndicator extends LitElement implements ILoadingIndicator {
19
16
  constructor() {
20
17
  super();
21
18
  this.hidden = true;
19
+ this.attachShadow({mode: "open"}).appendChild(document.createElement("slot"));
20
+ }
21
+
22
+ /**
23
+ * Registers the component.
24
+ */
25
+ static {
26
+ customElements.define("loading-indicator", this);
22
27
  }
23
28
 
24
29
  /**
@@ -42,14 +47,6 @@ export class LoadingIndicator extends LitElement implements ILoadingIndicator {
42
47
  document.body.classList.remove("loading");
43
48
  }
44
49
  }
45
-
46
- /**
47
- * Renders this component.
48
- * @returns The view template.
49
- */
50
- protected override render(): TemplateResult {
51
- return html`<slot></slot>`;
52
- }
53
50
  }
54
51
 
55
52
  /**
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A component that activates the items of a menu based on the current document URL.
3
+ */
4
+ export class MenuActivator extends HTMLElement {
5
+
6
+ /**
7
+ * Creates a new menu activator.
8
+ */
9
+ constructor() {
10
+ super();
11
+ this.attachShadow({mode: "open"}).appendChild(document.createElement("slot"));
12
+ }
13
+
14
+ /**
15
+ * Registers the component.
16
+ */
17
+ static {
18
+ customElements.define("menu-activator", this);
19
+ }
20
+
21
+ /**
22
+ * Method invoked when this component is connected.
23
+ */
24
+ connectedCallback(): void {
25
+ const menu = this.shadowRoot!.querySelector("slot")!.assignedElements().at(0);
26
+ if (menu) for (const anchor of menu.getElementsByTagName("a"))
27
+ if (anchor.href != location.href) anchor.classList.remove("active");
28
+ else {
29
+ anchor.classList.add("active");
30
+ anchor.closest(".nav-item.dropdown")?.querySelector(".nav-link")?.classList.add("active");
31
+ }
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Declaration merging.
37
+ */
38
+ declare global {
39
+
40
+ /**
41
+ * The map of HTML tag names.
42
+ */
43
+ interface HTMLElementTagNameMap {
44
+ "menu-activator": MenuActivator;
45
+ }
46
+ }
@@ -1,11 +1,7 @@
1
- import {html, LitElement, type TemplateResult} from "lit";
2
- import {customElement} from "lit/decorators.js";
3
-
4
1
  /**
5
2
  * A component that shows up when the network is unavailable, and hides when connectivity is restored.
6
3
  */
7
- @customElement("offline-indicator")
8
- export class OfflineIndicator extends LitElement {
4
+ export class OfflineIndicator extends HTMLElement {
9
5
 
10
6
  /**
11
7
  * Creates a new offline indicator.
@@ -13,22 +9,28 @@ export class OfflineIndicator extends LitElement {
13
9
  constructor() {
14
10
  super();
15
11
  this.hidden = navigator.onLine;
12
+ this.attachShadow({mode: "open"}).appendChild(document.createElement("slot"));
13
+ }
14
+
15
+ /**
16
+ * Registers the component.
17
+ */
18
+ static {
19
+ customElements.define("offline-indicator", this);
16
20
  }
17
21
 
18
22
  /**
19
23
  * Method invoked when this component is connected.
20
24
  */
21
- override connectedCallback(): void {
22
- super.connectedCallback();
25
+ connectedCallback(): void {
23
26
  for (const event of ["online", "offline"]) addEventListener(event, this);
24
27
  }
25
28
 
26
29
  /**
27
30
  * Method invoked when this component is disconnected.
28
31
  */
29
- override disconnectedCallback(): void {
32
+ disconnectedCallback(): void {
30
33
  for (const event of ["online", "offline"]) removeEventListener(event, this);
31
- super.disconnectedCallback();
32
34
  }
33
35
 
34
36
  /**
@@ -37,14 +39,6 @@ export class OfflineIndicator extends LitElement {
37
39
  handleEvent(): void {
38
40
  this.hidden = navigator.onLine;
39
41
  }
40
-
41
- /**
42
- * Renders this component.
43
- * @returns The view template.
44
- */
45
- protected override render(): TemplateResult {
46
- return html`<slot></slot>`;
47
- }
48
42
  }
49
43
 
50
44
  /**