@blackcube/aurelia2-bleet 1.0.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/blackcube-aurelia2-bleet-1.0.0.tgz +0 -0
- package/dist/index.es.js +4514 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.js +4549 -0
- package/dist/index.js.map +1 -0
- package/dist/types/attributes/ajaxify-trigger.d.ts +36 -0
- package/dist/types/attributes/ajaxify-trigger.d.ts.map +1 -0
- package/dist/types/attributes/alert.d.ts +15 -0
- package/dist/types/attributes/alert.d.ts.map +1 -0
- package/dist/types/attributes/badge.d.ts +13 -0
- package/dist/types/attributes/badge.d.ts.map +1 -0
- package/dist/types/attributes/burger.d.ts +11 -0
- package/dist/types/attributes/burger.d.ts.map +1 -0
- package/dist/types/attributes/drawer-trigger.d.ts +16 -0
- package/dist/types/attributes/drawer-trigger.d.ts.map +1 -0
- package/dist/types/attributes/dropdown.d.ts +38 -0
- package/dist/types/attributes/dropdown.d.ts.map +1 -0
- package/dist/types/attributes/index.d.ts +16 -0
- package/dist/types/attributes/index.d.ts.map +1 -0
- package/dist/types/attributes/menu.d.ts +32 -0
- package/dist/types/attributes/menu.d.ts.map +1 -0
- package/dist/types/attributes/modal-trigger.d.ts +16 -0
- package/dist/types/attributes/modal-trigger.d.ts.map +1 -0
- package/dist/types/attributes/pager.d.ts +13 -0
- package/dist/types/attributes/pager.d.ts.map +1 -0
- package/dist/types/attributes/password.d.ts +15 -0
- package/dist/types/attributes/password.d.ts.map +1 -0
- package/dist/types/attributes/profile.d.ts +24 -0
- package/dist/types/attributes/profile.d.ts.map +1 -0
- package/dist/types/attributes/select.d.ts +24 -0
- package/dist/types/attributes/select.d.ts.map +1 -0
- package/dist/types/attributes/tabs.d.ts +16 -0
- package/dist/types/attributes/tabs.d.ts.map +1 -0
- package/dist/types/attributes/toaster-trigger.d.ts +19 -0
- package/dist/types/attributes/toaster-trigger.d.ts.map +1 -0
- package/dist/types/attributes/upload.d.ts +57 -0
- package/dist/types/attributes/upload.d.ts.map +1 -0
- package/dist/types/codecs/ajaxify-codec.d.ts +5 -0
- package/dist/types/codecs/ajaxify-codec.d.ts.map +1 -0
- package/dist/types/codecs/csrf-codec.d.ts +7 -0
- package/dist/types/codecs/csrf-codec.d.ts.map +1 -0
- package/dist/types/codecs/request-codec.d.ts +5 -0
- package/dist/types/codecs/request-codec.d.ts.map +1 -0
- package/dist/types/components/bleet-ajaxify.d.ts +17 -0
- package/dist/types/components/bleet-ajaxify.d.ts.map +1 -0
- package/dist/types/components/bleet-ajaxify.html.d.ts +3 -0
- package/dist/types/components/bleet-ajaxify.html.d.ts.map +1 -0
- package/dist/types/components/bleet-drawer.d.ts +40 -0
- package/dist/types/components/bleet-drawer.d.ts.map +1 -0
- package/dist/types/components/bleet-drawer.html.d.ts +3 -0
- package/dist/types/components/bleet-drawer.html.d.ts.map +1 -0
- package/dist/types/components/bleet-modal.d.ts +46 -0
- package/dist/types/components/bleet-modal.d.ts.map +1 -0
- package/dist/types/components/bleet-modal.html.d.ts +3 -0
- package/dist/types/components/bleet-modal.html.d.ts.map +1 -0
- package/dist/types/components/bleet-overlay.d.ts +21 -0
- package/dist/types/components/bleet-overlay.d.ts.map +1 -0
- package/dist/types/components/bleet-quilljs.d.ts +19 -0
- package/dist/types/components/bleet-quilljs.d.ts.map +1 -0
- package/dist/types/components/bleet-quilljs.html.d.ts +3 -0
- package/dist/types/components/bleet-quilljs.html.d.ts.map +1 -0
- package/dist/types/components/bleet-toast.d.ts +26 -0
- package/dist/types/components/bleet-toast.d.ts.map +1 -0
- package/dist/types/components/bleet-toast.html.d.ts +3 -0
- package/dist/types/components/bleet-toast.html.d.ts.map +1 -0
- package/dist/types/components/bleet-toaster-trigger.d.ts +20 -0
- package/dist/types/components/bleet-toaster-trigger.d.ts.map +1 -0
- package/dist/types/components/bleet-toaster.d.ts +15 -0
- package/dist/types/components/bleet-toaster.d.ts.map +1 -0
- package/dist/types/components/bleet-toaster.html.d.ts +3 -0
- package/dist/types/components/bleet-toaster.html.d.ts.map +1 -0
- package/dist/types/components/index.d.ts +9 -0
- package/dist/types/components/index.d.ts.map +1 -0
- package/dist/types/configure.d.ts +35 -0
- package/dist/types/configure.d.ts.map +1 -0
- package/dist/types/enums/api.d.ts +11 -0
- package/dist/types/enums/api.d.ts.map +1 -0
- package/dist/types/enums/event-aggregator.d.ts +123 -0
- package/dist/types/enums/event-aggregator.d.ts.map +1 -0
- package/dist/types/index.d.ts +26 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interfaces/api.d.ts +56 -0
- package/dist/types/interfaces/api.d.ts.map +1 -0
- package/dist/types/interfaces/dialog.d.ts +18 -0
- package/dist/types/interfaces/dialog.d.ts.map +1 -0
- package/dist/types/interfaces/event-aggregator.d.ts +75 -0
- package/dist/types/interfaces/event-aggregator.d.ts.map +1 -0
- package/dist/types/services/api-service.d.ts +64 -0
- package/dist/types/services/api-service.d.ts.map +1 -0
- package/dist/types/services/http-service.d.ts +22 -0
- package/dist/types/services/http-service.d.ts.map +1 -0
- package/dist/types/services/socketio-service.d.ts +23 -0
- package/dist/types/services/socketio-service.d.ts.map +1 -0
- package/dist/types/services/storage-service.d.ts +13 -0
- package/dist/types/services/storage-service.d.ts.map +1 -0
- package/dist/types/services/svg-service.d.ts +17 -0
- package/dist/types/services/svg-service.d.ts.map +1 -0
- package/dist/types/services/transition-service.d.ts +13 -0
- package/dist/types/services/transition-service.d.ts.map +1 -0
- package/dist/types/services/trap-focus-service.d.ts +28 -0
- package/dist/types/services/trap-focus-service.d.ts.map +1 -0
- package/doc/bleet-api-reference.md +1333 -0
- package/doc/bleet-model-api-reference.md +379 -0
- package/doc/bleet-typescript-api-reference.md +1037 -0
- package/package.json +43 -0
- package/resource.d.ts +22 -0
- package/src/attributes/ajaxify-trigger.ts +218 -0
- package/src/attributes/alert.ts +55 -0
- package/src/attributes/badge.ts +39 -0
- package/src/attributes/burger.ts +36 -0
- package/src/attributes/drawer-trigger.ts +53 -0
- package/src/attributes/dropdown.ts +377 -0
- package/src/attributes/index.ts +15 -0
- package/src/attributes/menu.ts +179 -0
- package/src/attributes/modal-trigger.ts +53 -0
- package/src/attributes/pager.ts +43 -0
- package/src/attributes/password.ts +47 -0
- package/src/attributes/profile.ts +112 -0
- package/src/attributes/select.ts +214 -0
- package/src/attributes/tabs.ts +99 -0
- package/src/attributes/toaster-trigger.ts +54 -0
- package/src/attributes/upload.ts +380 -0
- package/src/codecs/ajaxify-codec.ts +16 -0
- package/src/codecs/csrf-codec.ts +41 -0
- package/src/codecs/request-codec.ts +16 -0
- package/src/components/bleet-ajaxify.html.ts +4 -0
- package/src/components/bleet-ajaxify.ts +62 -0
- package/src/components/bleet-drawer.html.ts +36 -0
- package/src/components/bleet-drawer.ts +236 -0
- package/src/components/bleet-modal.html.ts +30 -0
- package/src/components/bleet-modal.ts +274 -0
- package/src/components/bleet-overlay.ts +111 -0
- package/src/components/bleet-quilljs.html.ts +4 -0
- package/src/components/bleet-quilljs.ts +73 -0
- package/src/components/bleet-toast.html.ts +44 -0
- package/src/components/bleet-toast.ts +133 -0
- package/src/components/bleet-toaster-trigger.ts +66 -0
- package/src/components/bleet-toaster.html.ts +11 -0
- package/src/components/bleet-toaster.ts +72 -0
- package/src/components/index.ts +8 -0
- package/src/configure.ts +121 -0
- package/src/enums/api.ts +12 -0
- package/src/enums/event-aggregator.ts +131 -0
- package/src/index.ts +220 -0
- package/src/interfaces/api.ts +64 -0
- package/src/interfaces/dialog.ts +25 -0
- package/src/interfaces/event-aggregator.ts +88 -0
- package/src/services/api-service.ts +387 -0
- package/src/services/http-service.ts +166 -0
- package/src/services/socketio-service.ts +138 -0
- package/src/services/storage-service.ts +36 -0
- package/src/services/svg-service.ts +35 -0
- package/src/services/transition-service.ts +39 -0
- package/src/services/trap-focus-service.ts +213 -0
- package/src/types/css.d.ts +4 -0
- package/src/types/html.d.ts +12 -0
- package/src/types/svg.d.ts +4 -0
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blackcube/aurelia2-bleet",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Blackcube Aurelia 2 components for Bleet",
|
|
5
|
+
"author": "Gaultier Philippe <philippe@blackcube.io",
|
|
6
|
+
"license": "BSD-3-Clause",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"module": "./dist/index.es.js",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/types/index.d.ts",
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
13
|
+
"@types/node": "^22.10.2",
|
|
14
|
+
"rimraf": "^6.1.2",
|
|
15
|
+
"rollup": "^4.53.3",
|
|
16
|
+
"socket.io-client": "^4.8.1",
|
|
17
|
+
"tslib": "^2.8.1",
|
|
18
|
+
"typescript": "^5.9.3"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"aurelia": "^2.0.0-rc.0",
|
|
22
|
+
"quill": "^2.0.3",
|
|
23
|
+
"resumablejs": "^1.1.0",
|
|
24
|
+
"socket.io-client": "^4.8.1"
|
|
25
|
+
},
|
|
26
|
+
"peerDependenciesMeta": {
|
|
27
|
+
"resumablejs": {
|
|
28
|
+
"optional": false
|
|
29
|
+
},
|
|
30
|
+
"quill": {
|
|
31
|
+
"optional": false
|
|
32
|
+
},
|
|
33
|
+
"socket.io-client": {
|
|
34
|
+
"optional": true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"clean": "rimraf ./dist",
|
|
39
|
+
"build": "rollup -c",
|
|
40
|
+
"prebuild": "npm run clean && tsc --emitDeclarationOnly",
|
|
41
|
+
"build:watch": "rollup -cw"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/resource.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare module '*.html' {
|
|
2
|
+
import { IContainer, PartialBindableDefinition } from 'aurelia';
|
|
3
|
+
export const name: string;
|
|
4
|
+
export const template: string;
|
|
5
|
+
export default template;
|
|
6
|
+
export const dependencies: string[];
|
|
7
|
+
export const containerless: boolean | undefined;
|
|
8
|
+
export const bindables: Record<string, PartialBindableDefinition>;
|
|
9
|
+
export const shadowOptions: { mode: 'open' | 'closed' } | undefined;
|
|
10
|
+
export function register(container: IContainer);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare module '*.css';
|
|
14
|
+
declare module '*.scss';
|
|
15
|
+
|
|
16
|
+
// Extend resumablejs types - missing properties in official .d.ts
|
|
17
|
+
declare module Resumable {
|
|
18
|
+
interface ConfigurationHash {
|
|
19
|
+
permanentErrors?: number[];
|
|
20
|
+
maxChunkRetries?: number;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import {bindable, customAttribute, IEventAggregator, ILogger, INode, resolve} from "aurelia";
|
|
2
|
+
import {Channels, ToasterAction, UiColor} from '../enums/event-aggregator';
|
|
3
|
+
import {IAjaxifyResponse, IToast, IToaster} from '../interfaces/event-aggregator';
|
|
4
|
+
import {IApiService} from '../services/api-service';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generic AJAX trigger attribute for elements.
|
|
8
|
+
* Placed on the element that triggers the AJAX call.
|
|
9
|
+
* Looks up parent form with closest() to get URL/verb if not specified.
|
|
10
|
+
* Sends only the inputs contained within this.element.
|
|
11
|
+
* Pessimistic UI: state changes only on server response.
|
|
12
|
+
*
|
|
13
|
+
* Bindables:
|
|
14
|
+
* - url (primary): URL to call. Falls back to closest form.action.
|
|
15
|
+
* - verb: HTTP method. Falls back to closest form.method or 'POST'.
|
|
16
|
+
* - event: DOM event to listen for (default: 'click')
|
|
17
|
+
* - collect: If set, also collects inputs with data-ajaxify="{collect}" from closest form
|
|
18
|
+
*/
|
|
19
|
+
@customAttribute({ name: 'bleet-ajaxify-trigger', defaultProperty: 'url' })
|
|
20
|
+
export class BleetAjaxifyTriggerCustomAttribute {
|
|
21
|
+
|
|
22
|
+
@bindable url: string = '';
|
|
23
|
+
@bindable() verb: string = '';
|
|
24
|
+
@bindable() event: string = 'click';
|
|
25
|
+
@bindable() id: string = '';
|
|
26
|
+
|
|
27
|
+
public constructor(
|
|
28
|
+
private readonly logger: ILogger = resolve(ILogger).scopeTo('bleet-ajaxify-trigger'),
|
|
29
|
+
private readonly element: HTMLElement = resolve(INode) as HTMLElement,
|
|
30
|
+
private readonly ea: IEventAggregator = resolve(IEventAggregator),
|
|
31
|
+
private readonly apiService: IApiService = resolve(IApiService),
|
|
32
|
+
) {
|
|
33
|
+
this.logger.trace('constructor');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public attached(): void {
|
|
37
|
+
this.logger.trace('attached', { url: this.url, verb: this.verb, event: this.event });
|
|
38
|
+
this.element.addEventListener(this.event, this.onTrigger);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public detached(): void {
|
|
42
|
+
this.logger.trace('detached');
|
|
43
|
+
this.element.removeEventListener(this.event, this.onTrigger);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private onTrigger = (event: Event): void => {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
event.stopPropagation();
|
|
49
|
+
this.logger.trace('onTrigger', event);
|
|
50
|
+
|
|
51
|
+
const form = this.element.closest('form');
|
|
52
|
+
const url = this.resolveUrl(form);
|
|
53
|
+
const verb = this.resolveVerb(form);
|
|
54
|
+
|
|
55
|
+
if (!url) {
|
|
56
|
+
this.logger.warn('No URL found for ajaxify-trigger');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.logger.debug('onTrigger', { url, verb });
|
|
61
|
+
|
|
62
|
+
// Build FormData from inputs INSIDE this.element only
|
|
63
|
+
const formData = this.buildFormData(event);
|
|
64
|
+
|
|
65
|
+
this.apiService
|
|
66
|
+
.url(url)
|
|
67
|
+
.fromMultipart(formData)
|
|
68
|
+
.request<IAjaxifyResponse>(verb)
|
|
69
|
+
.then((response) => {
|
|
70
|
+
this.logger.debug('response', response.body);
|
|
71
|
+
|
|
72
|
+
// Update element from response HTML
|
|
73
|
+
if (response.body.element) {
|
|
74
|
+
this.updateElement(response.body.element);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Show toast if provided
|
|
78
|
+
if (response.body.toast) {
|
|
79
|
+
this.ea.publish(Channels.Toaster, <IToaster>{
|
|
80
|
+
action: ToasterAction.Add,
|
|
81
|
+
toast: response.body.toast
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Trigger ajaxify refresh if provided
|
|
86
|
+
if (response.body.ajaxify) {
|
|
87
|
+
this.ea.publish(Channels.Ajaxify, response.body.ajaxify);
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
.catch((error) => {
|
|
91
|
+
this.logger.error('AJAX request failed', error);
|
|
92
|
+
|
|
93
|
+
this.ea.publish(Channels.Toaster, <IToaster>{
|
|
94
|
+
action: ToasterAction.Add,
|
|
95
|
+
toast: {
|
|
96
|
+
color: UiColor.Danger,
|
|
97
|
+
title: 'Erreur',
|
|
98
|
+
content: 'Une erreur est survenue.',
|
|
99
|
+
duration: 5000,
|
|
100
|
+
} as IToast
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
private buildFormData(event: Event): FormData {
|
|
106
|
+
const formData = new FormData();
|
|
107
|
+
|
|
108
|
+
// Get all inputs inside this.element
|
|
109
|
+
const inputs = this.element.querySelectorAll('input, select, textarea');
|
|
110
|
+
this.appendInputsToFormData(formData, inputs);
|
|
111
|
+
|
|
112
|
+
// Capture submitter button name/value (for submit events)
|
|
113
|
+
if (event instanceof SubmitEvent && event.submitter) {
|
|
114
|
+
const submitter = event.submitter as HTMLButtonElement | HTMLInputElement;
|
|
115
|
+
if (submitter.name) {
|
|
116
|
+
formData.append(submitter.name, submitter.value || '');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Also get CSRF token from parent form if exists
|
|
121
|
+
const form = this.element.closest('form');
|
|
122
|
+
if (form) {
|
|
123
|
+
const csrfInput = form.querySelector('input[name="_csrf"]') as HTMLInputElement | null;
|
|
124
|
+
if (csrfInput) {
|
|
125
|
+
formData.append('_csrf', csrfInput.value);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// If id is set, also collect inputs with data-ajaxify="{id}" from the form
|
|
129
|
+
if (this.id) {
|
|
130
|
+
const ajaxifyInputs = form.querySelectorAll(`[data-ajaxify="${this.id}"]`);
|
|
131
|
+
this.appendInputsToFormData(formData, ajaxifyInputs);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return formData;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private appendInputsToFormData(formData: FormData, inputs: NodeListOf<Element>): void {
|
|
139
|
+
for (const input of Array.from(inputs)) {
|
|
140
|
+
if (input instanceof HTMLInputElement) {
|
|
141
|
+
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
142
|
+
if (input.checked && input.name) {
|
|
143
|
+
formData.append(input.name, input.value || 'on');
|
|
144
|
+
}
|
|
145
|
+
} else if (input.name) {
|
|
146
|
+
formData.append(input.name, input.value);
|
|
147
|
+
}
|
|
148
|
+
} else if (input instanceof HTMLSelectElement && input.name) {
|
|
149
|
+
formData.append(input.name, input.value);
|
|
150
|
+
} else if (input instanceof HTMLTextAreaElement && input.name) {
|
|
151
|
+
formData.append(input.name, input.value);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private resolveUrl(form: HTMLFormElement | null): string {
|
|
157
|
+
if (this.url) {
|
|
158
|
+
return this.url;
|
|
159
|
+
}
|
|
160
|
+
if (form) {
|
|
161
|
+
return form.action || '';
|
|
162
|
+
}
|
|
163
|
+
return '';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private resolveVerb(form: HTMLFormElement | null): string {
|
|
167
|
+
if (this.verb) {
|
|
168
|
+
return this.verb;
|
|
169
|
+
}
|
|
170
|
+
if (form) {
|
|
171
|
+
return form.method || 'POST';
|
|
172
|
+
}
|
|
173
|
+
return 'POST';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private updateElement(html: string): void {
|
|
177
|
+
const template = document.createElement('template');
|
|
178
|
+
template.innerHTML = html.trim();
|
|
179
|
+
const newElement = template.content.firstElementChild;
|
|
180
|
+
|
|
181
|
+
if (newElement) {
|
|
182
|
+
this.syncElement(this.element, newElement);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private syncElement(current: Element, incoming: Element): void {
|
|
187
|
+
// Sync attributes of current element
|
|
188
|
+
for (const attr of Array.from(incoming.attributes)) {
|
|
189
|
+
current.setAttribute(attr.name, attr.value);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Remove attributes that don't exist in incoming
|
|
193
|
+
for (const attr of Array.from(current.attributes)) {
|
|
194
|
+
if (!incoming.hasAttribute(attr.name)) {
|
|
195
|
+
current.removeAttribute(attr.name);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Sync input values for form elements
|
|
200
|
+
if (current instanceof HTMLInputElement && incoming instanceof HTMLInputElement) {
|
|
201
|
+
if (current.type === 'checkbox' || current.type === 'radio') {
|
|
202
|
+
current.checked = incoming.checked;
|
|
203
|
+
} else {
|
|
204
|
+
current.value = incoming.value;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Sync children recursively
|
|
209
|
+
const currentChildren = Array.from(current.children);
|
|
210
|
+
const incomingChildren = Array.from(incoming.children);
|
|
211
|
+
|
|
212
|
+
for (let i = 0; i < incomingChildren.length; i++) {
|
|
213
|
+
if (i < currentChildren.length) {
|
|
214
|
+
this.syncElement(currentChildren[i], incomingChildren[i]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {customAttribute, ILogger, INode, IPlatform, resolve} from "aurelia";
|
|
2
|
+
import {ITransitionService} from '../services/transition-service';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@customAttribute('bleet-alert')
|
|
6
|
+
export class BleetAlertCustomAttribute {
|
|
7
|
+
|
|
8
|
+
private closeButton?: HTMLButtonElement;
|
|
9
|
+
public constructor(
|
|
10
|
+
private readonly logger: ILogger = resolve(ILogger).scopeTo('bleet-alert'),
|
|
11
|
+
private readonly element: HTMLElement = resolve(INode) as HTMLElement,
|
|
12
|
+
private readonly platform: IPlatform = resolve(IPlatform),
|
|
13
|
+
private readonly transitionService: ITransitionService = resolve(ITransitionService),
|
|
14
|
+
) {
|
|
15
|
+
this.logger.trace('constructor')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public attaching()
|
|
19
|
+
{
|
|
20
|
+
this.logger.trace('attaching');
|
|
21
|
+
this.closeButton = this.element.querySelector('[data-alert=close]') as HTMLButtonElement;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public attached()
|
|
25
|
+
{
|
|
26
|
+
this.logger.trace('attached');
|
|
27
|
+
this.closeButton?.addEventListener('click', this.onClose);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public detached()
|
|
31
|
+
{
|
|
32
|
+
this.logger.trace('detached');
|
|
33
|
+
this.closeButton?.removeEventListener('click', this.onClose);
|
|
34
|
+
}
|
|
35
|
+
private onClose = (event: Event) => {
|
|
36
|
+
this.logger.trace('onClose', event);
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
this.transitionService.run(this.element, (element: HTMLElement) => {
|
|
39
|
+
const currentHeight = element.scrollHeight;
|
|
40
|
+
element.style.height = currentHeight + 'px';
|
|
41
|
+
// Force reflow
|
|
42
|
+
element.offsetHeight;
|
|
43
|
+
element.style.height = '0px';
|
|
44
|
+
element.classList.remove('opacity-100');
|
|
45
|
+
element.classList.add('opacity-0');
|
|
46
|
+
}, (element: HTMLElement) => {
|
|
47
|
+
|
|
48
|
+
element.classList.add('hidden');
|
|
49
|
+
this.platform.requestAnimationFrame(() => {
|
|
50
|
+
element.style.height = '';
|
|
51
|
+
element.remove();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {bindable, customAttribute, IEventAggregator, ILogger, INode, resolve} from "aurelia";
|
|
2
|
+
import {BadgeAction, Channels} from '../enums/event-aggregator';
|
|
3
|
+
import {IBadge} from '../interfaces/event-aggregator';
|
|
4
|
+
|
|
5
|
+
@customAttribute({ name: 'bleet-badge', defaultProperty: 'id' })
|
|
6
|
+
export class BleetBadgeCustomAttribute
|
|
7
|
+
{
|
|
8
|
+
private closeButton?: HTMLElement;
|
|
9
|
+
@bindable id: string = '';
|
|
10
|
+
public constructor(
|
|
11
|
+
private readonly logger: ILogger = resolve(ILogger).scopeTo('bleet-badge'),
|
|
12
|
+
private readonly ea:IEventAggregator = resolve(IEventAggregator),
|
|
13
|
+
private readonly element: HTMLButtonElement = resolve(INode) as HTMLButtonElement,
|
|
14
|
+
) {
|
|
15
|
+
this.logger.trace('constructor')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public attached()
|
|
19
|
+
{
|
|
20
|
+
this.logger.trace('attached');
|
|
21
|
+
this.closeButton = this.element.querySelector('[data-badge=remove]') ?? undefined;
|
|
22
|
+
this.closeButton?.addEventListener('click', this.onClickRemove);
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public detached()
|
|
27
|
+
{
|
|
28
|
+
this.logger.trace('detached');
|
|
29
|
+
this.closeButton?.removeEventListener('click', this.onClickRemove);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private onClickRemove = (event: MouseEvent) => {
|
|
33
|
+
this.logger.trace('onClickRemove', event);
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
this.ea.publish(Channels.Badge, <IBadge>{action: BadgeAction.Remove, id: this.id});
|
|
36
|
+
this.element.remove();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {customAttribute, IEventAggregator, ILogger, INode, resolve} from "aurelia";
|
|
2
|
+
import {Channels, MenuAction} from '../enums/event-aggregator';
|
|
3
|
+
import {IMenu} from '../interfaces/event-aggregator';
|
|
4
|
+
|
|
5
|
+
@customAttribute('bleet-burger')
|
|
6
|
+
export class BleetBurgerCustomAttribute
|
|
7
|
+
{
|
|
8
|
+
|
|
9
|
+
public constructor(
|
|
10
|
+
private readonly logger: ILogger = resolve(ILogger).scopeTo('bleet-burger'),
|
|
11
|
+
private readonly ea:IEventAggregator = resolve(IEventAggregator),
|
|
12
|
+
private readonly element: HTMLButtonElement = resolve(INode) as HTMLButtonElement,
|
|
13
|
+
) {
|
|
14
|
+
this.logger.trace('constructor')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public attached()
|
|
18
|
+
{
|
|
19
|
+
this.logger.trace('attached');
|
|
20
|
+
this.element.addEventListener('click', this.onClickButton);
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public detached()
|
|
25
|
+
{
|
|
26
|
+
this.logger.trace('detached');
|
|
27
|
+
this.element.removeEventListener('click', this.onClickButton);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private onClickButton = (event: MouseEvent) => {
|
|
31
|
+
this.logger.trace('onClickButton', event);
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
this.ea.publish(Channels.Menu, <IMenu>{action: MenuAction.Open});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {bindable, customAttribute, IEventAggregator, ILogger, INode, resolve} from "aurelia";
|
|
2
|
+
import {Channels, DrawerAction} from '../enums/event-aggregator';
|
|
3
|
+
import {IDrawer} from '../interfaces/event-aggregator';
|
|
4
|
+
|
|
5
|
+
@customAttribute({ name: 'bleet-drawer-trigger', defaultProperty: 'id' })
|
|
6
|
+
export class BleetDrawerTriggerCustomAttribute {
|
|
7
|
+
|
|
8
|
+
@bindable id: string = '';
|
|
9
|
+
@bindable() url: string = '';
|
|
10
|
+
@bindable() color: string = 'primary';
|
|
11
|
+
|
|
12
|
+
public constructor(
|
|
13
|
+
private readonly logger: ILogger = resolve(ILogger).scopeTo('bleet-drawer-trigger'),
|
|
14
|
+
private readonly element: HTMLElement = resolve(INode) as HTMLElement,
|
|
15
|
+
private readonly ea: IEventAggregator = resolve(IEventAggregator),
|
|
16
|
+
) {
|
|
17
|
+
this.logger.trace('constructor')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public attaching()
|
|
21
|
+
{
|
|
22
|
+
this.logger.trace('attaching');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public attached()
|
|
26
|
+
{
|
|
27
|
+
this.logger.trace('attached');
|
|
28
|
+
this.element.addEventListener('click', this.onClick);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public detached()
|
|
32
|
+
{
|
|
33
|
+
this.logger.trace('detached');
|
|
34
|
+
this.element.removeEventListener('click', this.onClick);
|
|
35
|
+
}
|
|
36
|
+
public dispose()
|
|
37
|
+
{
|
|
38
|
+
this.logger.trace('dispose');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private onClick = (event: Event): void => {
|
|
42
|
+
this.logger.trace('onClick', event);
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
|
|
45
|
+
this.ea.publish(Channels.Drawer, <IDrawer>{
|
|
46
|
+
action: DrawerAction.Toggle,
|
|
47
|
+
id: this.id,
|
|
48
|
+
url: this.url,
|
|
49
|
+
color: this.color,
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
}
|