@cedx/ui 0.1.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/License.md +20 -0
- package/ReadMe.md +17 -0
- package/lib/Alignment.d.ts +22 -0
- package/lib/Alignment.d.ts.map +1 -0
- package/lib/Alignment.js +17 -0
- package/lib/AppTheme.d.ts +34 -0
- package/lib/AppTheme.d.ts.map +1 -0
- package/lib/AppTheme.js +41 -0
- package/lib/Components/BackButton.d.ts +27 -0
- package/lib/Components/BackButton.d.ts.map +1 -0
- package/lib/Components/BackButton.js +29 -0
- package/lib/Components/DialogBox.d.ts +151 -0
- package/lib/Components/DialogBox.d.ts.map +1 -0
- package/lib/Components/DialogBox.js +268 -0
- package/lib/Components/FullScreenToggler.d.ts +42 -0
- package/lib/Components/FullScreenToggler.d.ts.map +1 -0
- package/lib/Components/FullScreenToggler.js +103 -0
- package/lib/Components/KeyboardAccelerator.d.ts +36 -0
- package/lib/Components/KeyboardAccelerator.d.ts.map +1 -0
- package/lib/Components/KeyboardAccelerator.js +78 -0
- package/lib/Components/LoadingIndicator.d.ts +58 -0
- package/lib/Components/LoadingIndicator.d.ts.map +1 -0
- package/lib/Components/LoadingIndicator.js +93 -0
- package/lib/Components/MenuActivator.d.ts +26 -0
- package/lib/Components/MenuActivator.d.ts.map +1 -0
- package/lib/Components/MenuActivator.js +42 -0
- package/lib/Components/OfflineIndicator.d.ts +59 -0
- package/lib/Components/OfflineIndicator.d.ts.map +1 -0
- package/lib/Components/OfflineIndicator.js +106 -0
- package/lib/Components/TabActivator.d.ts +49 -0
- package/lib/Components/TabActivator.d.ts.map +1 -0
- package/lib/Components/TabActivator.js +70 -0
- package/lib/Components/ThemeDropdown.d.ts +86 -0
- package/lib/Components/ThemeDropdown.d.ts.map +1 -0
- package/lib/Components/ThemeDropdown.js +207 -0
- package/lib/Components/Toast.d.ts +94 -0
- package/lib/Components/Toast.d.ts.map +1 -0
- package/lib/Components/Toast.js +284 -0
- package/lib/Components/Toaster.d.ts +119 -0
- package/lib/Components/Toaster.d.ts.map +1 -0
- package/lib/Components/Toaster.js +153 -0
- package/lib/Components/TypeAhead.d.ts +53 -0
- package/lib/Components/TypeAhead.d.ts.map +1 -0
- package/lib/Components/TypeAhead.js +138 -0
- package/lib/Context.d.ts +38 -0
- package/lib/Context.d.ts.map +1 -0
- package/lib/Context.js +42 -0
- package/lib/DialogResult.d.ts +30 -0
- package/lib/DialogResult.d.ts.map +1 -0
- package/lib/DialogResult.js +29 -0
- package/lib/File.d.ts +25 -0
- package/lib/File.d.ts.map +1 -0
- package/lib/File.js +66 -0
- package/lib/Form.d.ts +33 -0
- package/lib/Form.d.ts.map +1 -0
- package/lib/Form.js +50 -0
- package/lib/Htmx.d.ts +12 -0
- package/lib/Htmx.d.ts.map +1 -0
- package/lib/Htmx.js +2 -0
- package/lib/KeyboardModifiers.d.ts +26 -0
- package/lib/KeyboardModifiers.d.ts.map +1 -0
- package/lib/KeyboardModifiers.js +25 -0
- package/lib/Position.d.ts +52 -0
- package/lib/Position.d.ts.map +1 -0
- package/lib/Position.js +59 -0
- package/lib/Size.d.ts +40 -0
- package/lib/Size.d.ts.map +1 -0
- package/lib/Size.js +44 -0
- package/lib/StorageArea.d.ts +18 -0
- package/lib/StorageArea.d.ts.map +1 -0
- package/lib/StorageArea.js +13 -0
- package/lib/Tags.d.ts +15 -0
- package/lib/Tags.d.ts.map +1 -0
- package/lib/Tags.js +48 -0
- package/lib/Variant.d.ts +36 -0
- package/lib/Variant.d.ts.map +1 -0
- package/lib/Variant.js +31 -0
- package/lib/ViewportScroller.d.ts +49 -0
- package/lib/ViewportScroller.d.ts.map +1 -0
- package/lib/ViewportScroller.js +69 -0
- package/package.json +58 -0
- package/src/Client/Alignment.ts +25 -0
- package/src/Client/AppTheme.ts +51 -0
- package/src/Client/Components/BackButton.ts +45 -0
- package/src/Client/Components/DialogBox.ts +344 -0
- package/src/Client/Components/FullScreenToggler.ts +122 -0
- package/src/Client/Components/KeyboardAccelerator.ts +97 -0
- package/src/Client/Components/LoadingIndicator.ts +113 -0
- package/src/Client/Components/MenuActivator.ts +58 -0
- package/src/Client/Components/OfflineIndicator.ts +125 -0
- package/src/Client/Components/TabActivator.ts +93 -0
- package/src/Client/Components/ThemeDropdown.ts +235 -0
- package/src/Client/Components/Toast.ts +319 -0
- package/src/Client/Components/Toaster.ts +224 -0
- package/src/Client/Components/TypeAhead.ts +153 -0
- package/src/Client/Context.ts +53 -0
- package/src/Client/DialogResult.ts +35 -0
- package/src/Client/File.ts +73 -0
- package/src/Client/Form.ts +55 -0
- package/src/Client/Htmx.ts +13 -0
- package/src/Client/KeyboardModifiers.ts +30 -0
- package/src/Client/Position.ts +74 -0
- package/src/Client/Size.ts +56 -0
- package/src/Client/StorageArea.ts +20 -0
- package/src/Client/Tags.ts +58 -0
- package/src/Client/Variant.ts +42 -0
- package/src/Client/ViewportScroller.ts +89 -0
- package/src/Client/tsconfig.json +19 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A dynamic list of suggested values for an associated control.
|
|
3
|
+
*/
|
|
4
|
+
export class TypeAhead extends HTMLElement {
|
|
5
|
+
/**
|
|
6
|
+
* The list of observed attributes.
|
|
7
|
+
*/
|
|
8
|
+
static observedAttributes = ["list", "query"];
|
|
9
|
+
/**
|
|
10
|
+
* The debounced handler used to look up the query.
|
|
11
|
+
*/
|
|
12
|
+
#debounced = () => { };
|
|
13
|
+
/**
|
|
14
|
+
* The previous query.
|
|
15
|
+
*/
|
|
16
|
+
#previousQuery = "";
|
|
17
|
+
/**
|
|
18
|
+
* Registers the component.
|
|
19
|
+
*/
|
|
20
|
+
static {
|
|
21
|
+
customElements.define("type-ahead", this);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The delay in milliseconds to wait before triggering autocomplete suggestions.
|
|
25
|
+
*/
|
|
26
|
+
get delay() {
|
|
27
|
+
const value = Number(this.getAttribute("delay"));
|
|
28
|
+
return Math.max(0, Number.isNaN(value) ? 300 : value);
|
|
29
|
+
}
|
|
30
|
+
set delay(value) {
|
|
31
|
+
this.setAttribute("delay", value.toString());
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The function invoked when the query has been changed.
|
|
35
|
+
*/
|
|
36
|
+
set handler(callback) {
|
|
37
|
+
this.#debounced = this.#debounce(async (query) => {
|
|
38
|
+
try {
|
|
39
|
+
this.#updateItems(await callback(query));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
this.#updateItems([]);
|
|
43
|
+
}
|
|
44
|
+
}, this.delay);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The data list identifier.
|
|
48
|
+
*/
|
|
49
|
+
get list() {
|
|
50
|
+
return (this.getAttribute("list") ?? "").trim();
|
|
51
|
+
}
|
|
52
|
+
set list(value) {
|
|
53
|
+
this.setAttribute("list", value);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The minimum character length needed before triggering autocomplete suggestions.
|
|
57
|
+
*/
|
|
58
|
+
get minLength() {
|
|
59
|
+
const value = Number(this.getAttribute("minlength"));
|
|
60
|
+
return Math.max(1, Number.isNaN(value) ? 1 : value);
|
|
61
|
+
}
|
|
62
|
+
set minLength(value) {
|
|
63
|
+
this.setAttribute("minlength", value.toString());
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The query to look up.
|
|
67
|
+
*/
|
|
68
|
+
get query() {
|
|
69
|
+
return (this.getAttribute("query") ?? "").trim();
|
|
70
|
+
}
|
|
71
|
+
set query(value) {
|
|
72
|
+
this.setAttribute("query", value);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Method invoked when an attribute has been changed.
|
|
76
|
+
* @param attribute The attribute name.
|
|
77
|
+
* @param oldValue The previous attribute value.
|
|
78
|
+
* @param newValue The new attribute value.
|
|
79
|
+
*/
|
|
80
|
+
attributeChangedCallback(attribute, oldValue, newValue) {
|
|
81
|
+
if (newValue != oldValue)
|
|
82
|
+
switch (attribute) {
|
|
83
|
+
case "list":
|
|
84
|
+
this.#updateList(newValue ?? "");
|
|
85
|
+
break;
|
|
86
|
+
case "query":
|
|
87
|
+
this.#updateQuery(newValue ?? "");
|
|
88
|
+
break;
|
|
89
|
+
// No default
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Postpones the invocation of the specified callback until after a given delay has elapsed since the last time it was invoked.
|
|
94
|
+
* @param callback The function to debounce.
|
|
95
|
+
* @param delay The delay to wait, in milliseconds.
|
|
96
|
+
* @returns The debounced function.
|
|
97
|
+
*/
|
|
98
|
+
#debounce(callback, delay) {
|
|
99
|
+
let timer = 0;
|
|
100
|
+
return value => {
|
|
101
|
+
if (timer)
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
timer = window.setTimeout(callback, delay, value);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Updates the identifier of the underlying data list.
|
|
108
|
+
* @param value The new value.
|
|
109
|
+
*/
|
|
110
|
+
#updateList(value) {
|
|
111
|
+
this.firstElementChild.id = value.trim();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Updates the query to look up.
|
|
115
|
+
* @param value The new value.
|
|
116
|
+
*/
|
|
117
|
+
#updateQuery(value) {
|
|
118
|
+
const query = value.trim();
|
|
119
|
+
if (query != this.#previousQuery) {
|
|
120
|
+
this.#previousQuery = query;
|
|
121
|
+
if (query.length < this.minLength)
|
|
122
|
+
this.#updateItems([]);
|
|
123
|
+
else
|
|
124
|
+
this.#debounced(query);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Updates the items of the underlying data list.
|
|
129
|
+
* @param values The new values.
|
|
130
|
+
*/
|
|
131
|
+
#updateItems(values) {
|
|
132
|
+
this.firstElementChild.replaceChildren(...values.map(value => {
|
|
133
|
+
const option = document.createElement("option");
|
|
134
|
+
option.value = value;
|
|
135
|
+
return option;
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
package/lib/Context.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
* Returns the CSS class of the specified context.
|
|
28
|
+
* @param context The context.
|
|
29
|
+
* @returns The CSS class of the specified context.
|
|
30
|
+
*/
|
|
31
|
+
export declare function cssClass(context: Context): string;
|
|
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 declare function icon(context: Context): string;
|
|
38
|
+
//# sourceMappingURL=Context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Context.d.ts","sourceRoot":"","sources":["../src/Client/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,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAO7C"}
|
package/lib/Context.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
* Returns the CSS class of the specified context.
|
|
24
|
+
* @param context The context.
|
|
25
|
+
* @returns The CSS class of the specified context.
|
|
26
|
+
*/
|
|
27
|
+
export function cssClass(context) {
|
|
28
|
+
return context.toLowerCase();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Gets the icon corresponding to the specified context.
|
|
32
|
+
* @param context The context.
|
|
33
|
+
* @returns The icon corresponding to the specified context.
|
|
34
|
+
*/
|
|
35
|
+
export function icon(context) {
|
|
36
|
+
switch (context) {
|
|
37
|
+
case Context.Danger: return "error";
|
|
38
|
+
case Context.Success: return "check_circle";
|
|
39
|
+
case Context.Warning: return "warning";
|
|
40
|
+
default: return "info";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specifies common return values of a dialog box.
|
|
3
|
+
*/
|
|
4
|
+
export declare const DialogResult: Readonly<{
|
|
5
|
+
/**
|
|
6
|
+
* The dialog box does not return any value.
|
|
7
|
+
*/
|
|
8
|
+
None: "";
|
|
9
|
+
/**
|
|
10
|
+
* The return value of the dialog box is "OK".
|
|
11
|
+
*/
|
|
12
|
+
OK: "OK";
|
|
13
|
+
/**
|
|
14
|
+
* The return value of the dialog box is "Cancel".
|
|
15
|
+
*/
|
|
16
|
+
Cancel: "Cancel";
|
|
17
|
+
/**
|
|
18
|
+
* The return value of the dialog box is "Abort".
|
|
19
|
+
*/
|
|
20
|
+
Abort: "Abort";
|
|
21
|
+
/**
|
|
22
|
+
* The return value of the dialog box is "Retry".
|
|
23
|
+
*/
|
|
24
|
+
Retry: "Retry";
|
|
25
|
+
/**
|
|
26
|
+
* The return value of the dialog box is "Ignore".
|
|
27
|
+
*/
|
|
28
|
+
Ignore: "Ignore";
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=DialogResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogResult.d.ts","sourceRoot":"","sources":["../src/Client/DialogResult.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,YAAY;IAExB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specifies common return values of a dialog box.
|
|
3
|
+
*/
|
|
4
|
+
export const DialogResult = Object.freeze({
|
|
5
|
+
/**
|
|
6
|
+
* The dialog box does not return any value.
|
|
7
|
+
*/
|
|
8
|
+
None: "",
|
|
9
|
+
/**
|
|
10
|
+
* The return value of the dialog box is "OK".
|
|
11
|
+
*/
|
|
12
|
+
OK: "OK",
|
|
13
|
+
/**
|
|
14
|
+
* The return value of the dialog box is "Cancel".
|
|
15
|
+
*/
|
|
16
|
+
Cancel: "Cancel",
|
|
17
|
+
/**
|
|
18
|
+
* The return value of the dialog box is "Abort".
|
|
19
|
+
*/
|
|
20
|
+
Abort: "Abort",
|
|
21
|
+
/**
|
|
22
|
+
* The return value of the dialog box is "Retry".
|
|
23
|
+
*/
|
|
24
|
+
Retry: "Retry",
|
|
25
|
+
/**
|
|
26
|
+
* The return value of the dialog box is "Ignore".
|
|
27
|
+
*/
|
|
28
|
+
Ignore: "Ignore"
|
|
29
|
+
});
|
package/lib/File.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Downloads the specified file.
|
|
3
|
+
* @param file The file to be downloaded.
|
|
4
|
+
*/
|
|
5
|
+
export declare function download(file: File): void;
|
|
6
|
+
/**
|
|
7
|
+
* Opens the specified file.
|
|
8
|
+
* @param file The file to be opened.
|
|
9
|
+
* @param options Value indicating whether to open the file in a new tab.
|
|
10
|
+
*/
|
|
11
|
+
export declare function open(file: File, options?: {
|
|
12
|
+
newTab?: boolean;
|
|
13
|
+
}): void;
|
|
14
|
+
/**
|
|
15
|
+
* Prints the specified file.
|
|
16
|
+
* @param file The file to be printed.
|
|
17
|
+
*/
|
|
18
|
+
export declare function print(file: File): void;
|
|
19
|
+
/**
|
|
20
|
+
* Converts the specified file to a data URL.
|
|
21
|
+
* @param file The file to convert.
|
|
22
|
+
* @returns The data URL corresponding to the given file.
|
|
23
|
+
*/
|
|
24
|
+
export declare function toDataUrl(file: File): Promise<URL>;
|
|
25
|
+
//# sourceMappingURL=File.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"File.d.ts","sourceRoot":"","sources":["../src/Client/File.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAUzC;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAM,GAAG,IAAI,CAkBvE;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAatC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAOlD"}
|
package/lib/File.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Downloads the specified file.
|
|
3
|
+
* @param file The file to be downloaded.
|
|
4
|
+
*/
|
|
5
|
+
export function download(file) {
|
|
6
|
+
const url = URL.createObjectURL(file);
|
|
7
|
+
const anchor = document.createElement("a");
|
|
8
|
+
anchor.download = file.name;
|
|
9
|
+
anchor.href = url;
|
|
10
|
+
document.body.appendChild(anchor);
|
|
11
|
+
anchor.click();
|
|
12
|
+
document.body.removeChild(anchor);
|
|
13
|
+
URL.revokeObjectURL(url);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Opens the specified file.
|
|
17
|
+
* @param file The file to be opened.
|
|
18
|
+
* @param options Value indicating whether to open the file in a new tab.
|
|
19
|
+
*/
|
|
20
|
+
export function open(file, options = {}) {
|
|
21
|
+
const url = URL.createObjectURL(file);
|
|
22
|
+
if (!options.newTab) {
|
|
23
|
+
location.assign(url);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const handle = window.open(url, "_blank");
|
|
27
|
+
if (!handle) {
|
|
28
|
+
location.assign(url);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const timer = window.setInterval(() => {
|
|
32
|
+
if (!handle.closed)
|
|
33
|
+
return;
|
|
34
|
+
clearInterval(timer);
|
|
35
|
+
URL.revokeObjectURL(url);
|
|
36
|
+
}, 5_000);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Prints the specified file.
|
|
40
|
+
* @param file The file to be printed.
|
|
41
|
+
*/
|
|
42
|
+
export function print(file) {
|
|
43
|
+
const url = URL.createObjectURL(file);
|
|
44
|
+
const frame = document.createElement("iframe");
|
|
45
|
+
frame.addEventListener("load", () => frame.contentWindow?.print());
|
|
46
|
+
frame.hidden = true;
|
|
47
|
+
frame.src = url;
|
|
48
|
+
window.addEventListener("focus", () => {
|
|
49
|
+
document.body.removeChild(frame);
|
|
50
|
+
URL.revokeObjectURL(url);
|
|
51
|
+
}, { once: true });
|
|
52
|
+
document.body.appendChild(frame);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Converts the specified file to a data URL.
|
|
56
|
+
* @param file The file to convert.
|
|
57
|
+
* @returns The data URL corresponding to the given file.
|
|
58
|
+
*/
|
|
59
|
+
export function toDataUrl(file) {
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const reader = new FileReader;
|
|
62
|
+
reader.addEventListener("error", reject);
|
|
63
|
+
reader.addEventListener("load", () => resolve(new URL(reader.result)));
|
|
64
|
+
reader.readAsDataURL(file);
|
|
65
|
+
});
|
|
66
|
+
}
|
package/lib/Form.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a form control.
|
|
3
|
+
*/
|
|
4
|
+
export type FormControl = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
|
5
|
+
/**
|
|
6
|
+
* Gets all controls belonging to the specified form.
|
|
7
|
+
* @param form The form element.
|
|
8
|
+
* @returns The controls belonging to the specified form.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getControls(form: HTMLFormElement): FormControl[];
|
|
11
|
+
/**
|
|
12
|
+
* Returns the first invalid control from the specified form.
|
|
13
|
+
* @param form The form element.
|
|
14
|
+
* @returns The first invalid control, or `null` if all controls are valid.
|
|
15
|
+
*/
|
|
16
|
+
export declare function invalidControl(form: HTMLFormElement): FormControl | null;
|
|
17
|
+
/**
|
|
18
|
+
* Returns a value indicating whether the specified element is a form control.
|
|
19
|
+
* @param element The element to check.
|
|
20
|
+
* @returns `true` if the specified element is a form control, otherwise `false`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isControl(element: Element): element is FormControl;
|
|
23
|
+
/**
|
|
24
|
+
* Resets the validity of the specified element.
|
|
25
|
+
* @param element The element to process.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resetValidity(element: Element): void;
|
|
28
|
+
/**
|
|
29
|
+
* Removes whitespace from both ends of the value of the specified element.
|
|
30
|
+
* @param element The element to process.
|
|
31
|
+
*/
|
|
32
|
+
export declare function trimControl(element: Element): void;
|
|
33
|
+
//# sourceMappingURL=Form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../src/Client/Form.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAC,iBAAiB,GAAC,mBAAmB,CAAC;AAEjF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,EAAE,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,GAAC,IAAI,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,WAAW,CAElE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGpD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAIlD"}
|
package/lib/Form.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The types of form controls that are not text inputs.
|
|
3
|
+
*/
|
|
4
|
+
const nonTextualTypes = new Set(["button", "checkbox", "file", "hidden", "image", "password", "radio", "range", "reset", "submit"]);
|
|
5
|
+
/**
|
|
6
|
+
* Gets all controls belonging to the specified form.
|
|
7
|
+
* @param form The form element.
|
|
8
|
+
* @returns The controls belonging to the specified form.
|
|
9
|
+
*/
|
|
10
|
+
export function getControls(form) {
|
|
11
|
+
return Array.from(form.elements).filter(isControl);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Returns the first invalid control from the specified form.
|
|
15
|
+
* @param form The form element.
|
|
16
|
+
* @returns The first invalid control, or `null` if all controls are valid.
|
|
17
|
+
*/
|
|
18
|
+
export function invalidControl(form) {
|
|
19
|
+
return form.querySelector(":not(fieldset):invalid");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns a value indicating whether the specified element is a form control.
|
|
23
|
+
* @param element The element to check.
|
|
24
|
+
* @returns `true` if the specified element is a form control, otherwise `false`.
|
|
25
|
+
*/
|
|
26
|
+
export function isControl(element) {
|
|
27
|
+
return element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resets the validity of the specified element.
|
|
31
|
+
* @param element The element to process.
|
|
32
|
+
*/
|
|
33
|
+
export function resetValidity(element) {
|
|
34
|
+
if (element instanceof HTMLFormElement)
|
|
35
|
+
getControls(element).forEach(control => control.setCustomValidity(""));
|
|
36
|
+
else if (isControl(element))
|
|
37
|
+
element.setCustomValidity("");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Removes whitespace from both ends of the value of the specified element.
|
|
41
|
+
* @param element The element to process.
|
|
42
|
+
*/
|
|
43
|
+
export function trimControl(element) {
|
|
44
|
+
if (element instanceof HTMLFormElement)
|
|
45
|
+
getControls(element).forEach(trimControl);
|
|
46
|
+
else if (element instanceof HTMLInputElement && !nonTextualTypes.has(element.type))
|
|
47
|
+
element.value = element.value.trim();
|
|
48
|
+
else if (element instanceof HTMLTextAreaElement)
|
|
49
|
+
element.value = element.value.trim();
|
|
50
|
+
}
|
package/lib/Htmx.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import htmx, { type HtmxResponseInfo } from "htmx.org";
|
|
2
|
+
export declare const Htmx: typeof htmx.default;
|
|
3
|
+
/**
|
|
4
|
+
* Provides details about an `htmx` event.
|
|
5
|
+
*/
|
|
6
|
+
export type HtmxEventDetail = HtmxResponseInfo & {
|
|
7
|
+
/**
|
|
8
|
+
* The element involved in the operation that just occurred.
|
|
9
|
+
*/
|
|
10
|
+
elt: Element;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=Htmx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Htmx.d.ts","sourceRoot":"","sources":["../src/Client/Htmx.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAC,KAAK,gBAAgB,EAAC,MAAM,UAAU,CAAC;AACrD,eAAO,MAAM,IAAI,EAAsB,OAAO,IAAI,CAAC,OAAO,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG;IAEhD;;OAEG;IACH,GAAG,EAAE,OAAO,CAAC;CACb,CAAC"}
|
package/lib/Htmx.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumerates modifier flags for keyboard accelerators.
|
|
3
|
+
*/
|
|
4
|
+
export declare const KeyboardModifiers: Readonly<{
|
|
5
|
+
/**
|
|
6
|
+
* Indicates no modifier.
|
|
7
|
+
*/
|
|
8
|
+
None: 0;
|
|
9
|
+
/**
|
|
10
|
+
* Indicates the `Control` modifier.
|
|
11
|
+
*/
|
|
12
|
+
Ctrl: 1;
|
|
13
|
+
/**
|
|
14
|
+
* Indicates the `Shift` modifier.
|
|
15
|
+
*/
|
|
16
|
+
Shift: 2;
|
|
17
|
+
/**
|
|
18
|
+
* Indicates the `Alt` modifier (`Option` key on macOS, `Menu` key on Windows).
|
|
19
|
+
*/
|
|
20
|
+
Alt: 4;
|
|
21
|
+
/**
|
|
22
|
+
* Indicates the `Meta` modifier (`Command` key on macOS, `Windows` key on Windows).
|
|
23
|
+
*/
|
|
24
|
+
Meta: 8;
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=KeyboardModifiers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyboardModifiers.d.ts","sourceRoot":"","sources":["../src/Client/KeyboardModifiers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iBAAiB;IAE7B;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumerates modifier flags for keyboard accelerators.
|
|
3
|
+
*/
|
|
4
|
+
export const KeyboardModifiers = Object.freeze({
|
|
5
|
+
/**
|
|
6
|
+
* Indicates no modifier.
|
|
7
|
+
*/
|
|
8
|
+
None: 0,
|
|
9
|
+
/**
|
|
10
|
+
* Indicates the `Control` modifier.
|
|
11
|
+
*/
|
|
12
|
+
Ctrl: 1,
|
|
13
|
+
/**
|
|
14
|
+
* Indicates the `Shift` modifier.
|
|
15
|
+
*/
|
|
16
|
+
Shift: 2,
|
|
17
|
+
/**
|
|
18
|
+
* Indicates the `Alt` modifier (`Option` key on macOS, `Menu` key on Windows).
|
|
19
|
+
*/
|
|
20
|
+
Alt: 4,
|
|
21
|
+
/**
|
|
22
|
+
* Indicates the `Meta` modifier (`Command` key on macOS, `Windows` key on Windows).
|
|
23
|
+
*/
|
|
24
|
+
Meta: 8
|
|
25
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines the position of an element.
|
|
3
|
+
*/
|
|
4
|
+
export declare const Position: Readonly<{
|
|
5
|
+
/**
|
|
6
|
+
* Top left.
|
|
7
|
+
*/
|
|
8
|
+
TopStart: "TopStart";
|
|
9
|
+
/**
|
|
10
|
+
* Top center.
|
|
11
|
+
*/
|
|
12
|
+
TopCenter: "TopCenter";
|
|
13
|
+
/**
|
|
14
|
+
* Top right.
|
|
15
|
+
*/
|
|
16
|
+
TopEnd: "TopEnd";
|
|
17
|
+
/**
|
|
18
|
+
* Middle left.
|
|
19
|
+
*/
|
|
20
|
+
MiddleStart: "MiddleStart";
|
|
21
|
+
/**
|
|
22
|
+
* Middle center.
|
|
23
|
+
*/
|
|
24
|
+
MiddleCenter: "MiddleCenter";
|
|
25
|
+
/**
|
|
26
|
+
* Middle right.
|
|
27
|
+
*/
|
|
28
|
+
MiddleEnd: "MiddleEnd";
|
|
29
|
+
/**
|
|
30
|
+
* Bottom left.
|
|
31
|
+
*/
|
|
32
|
+
BottomStart: "BottomStart";
|
|
33
|
+
/**
|
|
34
|
+
* Bottom center.
|
|
35
|
+
*/
|
|
36
|
+
BottomCenter: "BottomCenter";
|
|
37
|
+
/**
|
|
38
|
+
* Bottom right.
|
|
39
|
+
*/
|
|
40
|
+
BottomEnd: "BottomEnd";
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Defines the placement of an element.
|
|
44
|
+
*/
|
|
45
|
+
export type Position = typeof Position[keyof typeof Position];
|
|
46
|
+
/**
|
|
47
|
+
* Returns the CSS class of the specified position.
|
|
48
|
+
* @param position The position.
|
|
49
|
+
* @returns The CSS class of the specified position.
|
|
50
|
+
*/
|
|
51
|
+
export declare function cssClass(position: Position): string;
|
|
52
|
+
//# sourceMappingURL=Position.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Position.d.ts","sourceRoot":"","sources":["../src/Client/Position.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ;IAEpB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;EAEF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAYnD"}
|
package/lib/Position.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines the position of an element.
|
|
3
|
+
*/
|
|
4
|
+
export const Position = Object.freeze({
|
|
5
|
+
/**
|
|
6
|
+
* Top left.
|
|
7
|
+
*/
|
|
8
|
+
TopStart: "TopStart",
|
|
9
|
+
/**
|
|
10
|
+
* Top center.
|
|
11
|
+
*/
|
|
12
|
+
TopCenter: "TopCenter",
|
|
13
|
+
/**
|
|
14
|
+
* Top right.
|
|
15
|
+
*/
|
|
16
|
+
TopEnd: "TopEnd",
|
|
17
|
+
/**
|
|
18
|
+
* Middle left.
|
|
19
|
+
*/
|
|
20
|
+
MiddleStart: "MiddleStart",
|
|
21
|
+
/**
|
|
22
|
+
* Middle center.
|
|
23
|
+
*/
|
|
24
|
+
MiddleCenter: "MiddleCenter",
|
|
25
|
+
/**
|
|
26
|
+
* Middle right.
|
|
27
|
+
*/
|
|
28
|
+
MiddleEnd: "MiddleEnd",
|
|
29
|
+
/**
|
|
30
|
+
* Bottom left.
|
|
31
|
+
*/
|
|
32
|
+
BottomStart: "BottomStart",
|
|
33
|
+
/**
|
|
34
|
+
* Bottom center.
|
|
35
|
+
*/
|
|
36
|
+
BottomCenter: "BottomCenter",
|
|
37
|
+
/**
|
|
38
|
+
* Bottom right.
|
|
39
|
+
*/
|
|
40
|
+
BottomEnd: "BottomEnd"
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Returns the CSS class of the specified position.
|
|
44
|
+
* @param position The position.
|
|
45
|
+
* @returns The CSS class of the specified position.
|
|
46
|
+
*/
|
|
47
|
+
export function cssClass(position) {
|
|
48
|
+
switch (position) {
|
|
49
|
+
case Position.TopCenter: return "top-0 start-50 translate-middle-x";
|
|
50
|
+
case Position.TopEnd: return "top-0 end-0";
|
|
51
|
+
case Position.MiddleStart: return "top-50 start-0 translate-middle-y";
|
|
52
|
+
case Position.MiddleCenter: return "top-50 start-50 translate-middle";
|
|
53
|
+
case Position.MiddleEnd: return "top-50 end-0 translate-middle-y";
|
|
54
|
+
case Position.BottomStart: return "bottom-0 start-0";
|
|
55
|
+
case Position.BottomCenter: return "bottom-0 start-50 translate-middle-x";
|
|
56
|
+
case Position.BottomEnd: return "bottom-0 end-0";
|
|
57
|
+
default: return "top-0 start-0";
|
|
58
|
+
}
|
|
59
|
+
}
|