@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.
Files changed (157) hide show
  1. package/blackcube-aurelia2-bleet-1.0.0.tgz +0 -0
  2. package/dist/index.es.js +4514 -0
  3. package/dist/index.es.js.map +1 -0
  4. package/dist/index.js +4549 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/types/attributes/ajaxify-trigger.d.ts +36 -0
  7. package/dist/types/attributes/ajaxify-trigger.d.ts.map +1 -0
  8. package/dist/types/attributes/alert.d.ts +15 -0
  9. package/dist/types/attributes/alert.d.ts.map +1 -0
  10. package/dist/types/attributes/badge.d.ts +13 -0
  11. package/dist/types/attributes/badge.d.ts.map +1 -0
  12. package/dist/types/attributes/burger.d.ts +11 -0
  13. package/dist/types/attributes/burger.d.ts.map +1 -0
  14. package/dist/types/attributes/drawer-trigger.d.ts +16 -0
  15. package/dist/types/attributes/drawer-trigger.d.ts.map +1 -0
  16. package/dist/types/attributes/dropdown.d.ts +38 -0
  17. package/dist/types/attributes/dropdown.d.ts.map +1 -0
  18. package/dist/types/attributes/index.d.ts +16 -0
  19. package/dist/types/attributes/index.d.ts.map +1 -0
  20. package/dist/types/attributes/menu.d.ts +32 -0
  21. package/dist/types/attributes/menu.d.ts.map +1 -0
  22. package/dist/types/attributes/modal-trigger.d.ts +16 -0
  23. package/dist/types/attributes/modal-trigger.d.ts.map +1 -0
  24. package/dist/types/attributes/pager.d.ts +13 -0
  25. package/dist/types/attributes/pager.d.ts.map +1 -0
  26. package/dist/types/attributes/password.d.ts +15 -0
  27. package/dist/types/attributes/password.d.ts.map +1 -0
  28. package/dist/types/attributes/profile.d.ts +24 -0
  29. package/dist/types/attributes/profile.d.ts.map +1 -0
  30. package/dist/types/attributes/select.d.ts +24 -0
  31. package/dist/types/attributes/select.d.ts.map +1 -0
  32. package/dist/types/attributes/tabs.d.ts +16 -0
  33. package/dist/types/attributes/tabs.d.ts.map +1 -0
  34. package/dist/types/attributes/toaster-trigger.d.ts +19 -0
  35. package/dist/types/attributes/toaster-trigger.d.ts.map +1 -0
  36. package/dist/types/attributes/upload.d.ts +57 -0
  37. package/dist/types/attributes/upload.d.ts.map +1 -0
  38. package/dist/types/codecs/ajaxify-codec.d.ts +5 -0
  39. package/dist/types/codecs/ajaxify-codec.d.ts.map +1 -0
  40. package/dist/types/codecs/csrf-codec.d.ts +7 -0
  41. package/dist/types/codecs/csrf-codec.d.ts.map +1 -0
  42. package/dist/types/codecs/request-codec.d.ts +5 -0
  43. package/dist/types/codecs/request-codec.d.ts.map +1 -0
  44. package/dist/types/components/bleet-ajaxify.d.ts +17 -0
  45. package/dist/types/components/bleet-ajaxify.d.ts.map +1 -0
  46. package/dist/types/components/bleet-ajaxify.html.d.ts +3 -0
  47. package/dist/types/components/bleet-ajaxify.html.d.ts.map +1 -0
  48. package/dist/types/components/bleet-drawer.d.ts +40 -0
  49. package/dist/types/components/bleet-drawer.d.ts.map +1 -0
  50. package/dist/types/components/bleet-drawer.html.d.ts +3 -0
  51. package/dist/types/components/bleet-drawer.html.d.ts.map +1 -0
  52. package/dist/types/components/bleet-modal.d.ts +46 -0
  53. package/dist/types/components/bleet-modal.d.ts.map +1 -0
  54. package/dist/types/components/bleet-modal.html.d.ts +3 -0
  55. package/dist/types/components/bleet-modal.html.d.ts.map +1 -0
  56. package/dist/types/components/bleet-overlay.d.ts +21 -0
  57. package/dist/types/components/bleet-overlay.d.ts.map +1 -0
  58. package/dist/types/components/bleet-quilljs.d.ts +19 -0
  59. package/dist/types/components/bleet-quilljs.d.ts.map +1 -0
  60. package/dist/types/components/bleet-quilljs.html.d.ts +3 -0
  61. package/dist/types/components/bleet-quilljs.html.d.ts.map +1 -0
  62. package/dist/types/components/bleet-toast.d.ts +26 -0
  63. package/dist/types/components/bleet-toast.d.ts.map +1 -0
  64. package/dist/types/components/bleet-toast.html.d.ts +3 -0
  65. package/dist/types/components/bleet-toast.html.d.ts.map +1 -0
  66. package/dist/types/components/bleet-toaster-trigger.d.ts +20 -0
  67. package/dist/types/components/bleet-toaster-trigger.d.ts.map +1 -0
  68. package/dist/types/components/bleet-toaster.d.ts +15 -0
  69. package/dist/types/components/bleet-toaster.d.ts.map +1 -0
  70. package/dist/types/components/bleet-toaster.html.d.ts +3 -0
  71. package/dist/types/components/bleet-toaster.html.d.ts.map +1 -0
  72. package/dist/types/components/index.d.ts +9 -0
  73. package/dist/types/components/index.d.ts.map +1 -0
  74. package/dist/types/configure.d.ts +35 -0
  75. package/dist/types/configure.d.ts.map +1 -0
  76. package/dist/types/enums/api.d.ts +11 -0
  77. package/dist/types/enums/api.d.ts.map +1 -0
  78. package/dist/types/enums/event-aggregator.d.ts +123 -0
  79. package/dist/types/enums/event-aggregator.d.ts.map +1 -0
  80. package/dist/types/index.d.ts +26 -0
  81. package/dist/types/index.d.ts.map +1 -0
  82. package/dist/types/interfaces/api.d.ts +56 -0
  83. package/dist/types/interfaces/api.d.ts.map +1 -0
  84. package/dist/types/interfaces/dialog.d.ts +18 -0
  85. package/dist/types/interfaces/dialog.d.ts.map +1 -0
  86. package/dist/types/interfaces/event-aggregator.d.ts +75 -0
  87. package/dist/types/interfaces/event-aggregator.d.ts.map +1 -0
  88. package/dist/types/services/api-service.d.ts +64 -0
  89. package/dist/types/services/api-service.d.ts.map +1 -0
  90. package/dist/types/services/http-service.d.ts +22 -0
  91. package/dist/types/services/http-service.d.ts.map +1 -0
  92. package/dist/types/services/socketio-service.d.ts +23 -0
  93. package/dist/types/services/socketio-service.d.ts.map +1 -0
  94. package/dist/types/services/storage-service.d.ts +13 -0
  95. package/dist/types/services/storage-service.d.ts.map +1 -0
  96. package/dist/types/services/svg-service.d.ts +17 -0
  97. package/dist/types/services/svg-service.d.ts.map +1 -0
  98. package/dist/types/services/transition-service.d.ts +13 -0
  99. package/dist/types/services/transition-service.d.ts.map +1 -0
  100. package/dist/types/services/trap-focus-service.d.ts +28 -0
  101. package/dist/types/services/trap-focus-service.d.ts.map +1 -0
  102. package/doc/bleet-api-reference.md +1333 -0
  103. package/doc/bleet-model-api-reference.md +379 -0
  104. package/doc/bleet-typescript-api-reference.md +1037 -0
  105. package/package.json +43 -0
  106. package/resource.d.ts +22 -0
  107. package/src/attributes/ajaxify-trigger.ts +218 -0
  108. package/src/attributes/alert.ts +55 -0
  109. package/src/attributes/badge.ts +39 -0
  110. package/src/attributes/burger.ts +36 -0
  111. package/src/attributes/drawer-trigger.ts +53 -0
  112. package/src/attributes/dropdown.ts +377 -0
  113. package/src/attributes/index.ts +15 -0
  114. package/src/attributes/menu.ts +179 -0
  115. package/src/attributes/modal-trigger.ts +53 -0
  116. package/src/attributes/pager.ts +43 -0
  117. package/src/attributes/password.ts +47 -0
  118. package/src/attributes/profile.ts +112 -0
  119. package/src/attributes/select.ts +214 -0
  120. package/src/attributes/tabs.ts +99 -0
  121. package/src/attributes/toaster-trigger.ts +54 -0
  122. package/src/attributes/upload.ts +380 -0
  123. package/src/codecs/ajaxify-codec.ts +16 -0
  124. package/src/codecs/csrf-codec.ts +41 -0
  125. package/src/codecs/request-codec.ts +16 -0
  126. package/src/components/bleet-ajaxify.html.ts +4 -0
  127. package/src/components/bleet-ajaxify.ts +62 -0
  128. package/src/components/bleet-drawer.html.ts +36 -0
  129. package/src/components/bleet-drawer.ts +236 -0
  130. package/src/components/bleet-modal.html.ts +30 -0
  131. package/src/components/bleet-modal.ts +274 -0
  132. package/src/components/bleet-overlay.ts +111 -0
  133. package/src/components/bleet-quilljs.html.ts +4 -0
  134. package/src/components/bleet-quilljs.ts +73 -0
  135. package/src/components/bleet-toast.html.ts +44 -0
  136. package/src/components/bleet-toast.ts +133 -0
  137. package/src/components/bleet-toaster-trigger.ts +66 -0
  138. package/src/components/bleet-toaster.html.ts +11 -0
  139. package/src/components/bleet-toaster.ts +72 -0
  140. package/src/components/index.ts +8 -0
  141. package/src/configure.ts +121 -0
  142. package/src/enums/api.ts +12 -0
  143. package/src/enums/event-aggregator.ts +131 -0
  144. package/src/index.ts +220 -0
  145. package/src/interfaces/api.ts +64 -0
  146. package/src/interfaces/dialog.ts +25 -0
  147. package/src/interfaces/event-aggregator.ts +88 -0
  148. package/src/services/api-service.ts +387 -0
  149. package/src/services/http-service.ts +166 -0
  150. package/src/services/socketio-service.ts +138 -0
  151. package/src/services/storage-service.ts +36 -0
  152. package/src/services/svg-service.ts +35 -0
  153. package/src/services/transition-service.ts +39 -0
  154. package/src/services/trap-focus-service.ts +213 -0
  155. package/src/types/css.d.ts +4 -0
  156. package/src/types/html.d.ts +12 -0
  157. package/src/types/svg.d.ts +4 -0
@@ -0,0 +1,36 @@
1
+ import {DI, ILogger, IPlatform, resolve} from "aurelia";
2
+
3
+ export interface IStorageService extends StorageService { }
4
+ export const IStorageService = /*@__PURE__*/DI.createInterface<IStorageService>('IStorageService', (x) => x.singleton(StorageService));
5
+
6
+ export class StorageService
7
+ {
8
+ public constructor(
9
+ private readonly logger: ILogger = resolve(ILogger).scopeTo('StorageService'),
10
+ private readonly platform:IPlatform = resolve(IPlatform),
11
+ ) {
12
+ this.logger.trace('constructor')
13
+ }
14
+
15
+ public load(key: string, def: any = null): any
16
+ {
17
+ this.logger.trace('load', key);
18
+ const value = localStorage.getItem(key);
19
+ if (value === null) {
20
+ return def;
21
+ }
22
+ return JSON.parse(value);
23
+ }
24
+
25
+ public save(key: string, value: any): void
26
+ {
27
+ this.logger.trace('save', key, value);
28
+ localStorage.setItem(key, JSON.stringify(value));
29
+ }
30
+
31
+ public remove(key: string): void
32
+ {
33
+ this.logger.trace('remove', key);
34
+ localStorage.removeItem(key);
35
+ }
36
+ }
@@ -0,0 +1,35 @@
1
+ import { DI, ILogger, resolve } from "aurelia";
2
+
3
+ export interface ISvgService extends SvgService { }
4
+ export const ISvgService = /*@__PURE__*/DI.createInterface<ISvgService>('ISvgService', (x) => x.singleton(SvgService));
5
+
6
+ export class SvgService {
7
+ private static readonly ICONS: Record<string, string> = {
8
+ 'information-circle': `<svg class="size-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 0 1 .67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 1 1-.671-1.34l.041-.022ZM12 9a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z" clip-rule="evenodd"/></svg>`,
9
+ 'check-circle': `<svg class="size-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z" clip-rule="evenodd"/></svg>`,
10
+ 'exclamation-triangle': `<svg class="size-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003ZM12 8.25a.75.75 0 0 1 .75.75v3.75a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75Zm0 8.25a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z" clip-rule="evenodd"/></svg>`,
11
+ 'x-circle': `<svg class="size-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm-1.72 6.97a.75.75 0 1 0-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 1 0 1.06 1.06L12 13.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L13.06 12l1.72-1.72a.75.75 0 1 0-1.06-1.06L12 10.94l-1.72-1.72Z" clip-rule="evenodd"/></svg>`,
12
+ 'x-mark': `<svg class="size-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.47 5.47a.75.75 0 0 1 1.06 0L12 10.94l5.47-5.47a.75.75 0 1 1 1.06 1.06L13.06 12l5.47 5.47a.75.75 0 1 1-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 0 1-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/></svg>`,
13
+ };
14
+
15
+ public constructor(
16
+ private readonly logger: ILogger = resolve(ILogger).scopeTo('SvgService'),
17
+ ) {
18
+ this.logger.trace('constructor');
19
+ }
20
+
21
+ /**
22
+ * Retourne le SVG pour une icône
23
+ * @param icon Clé heroicon (ex: 'check-circle') ou SVG inline custom
24
+ * @returns Le SVG du map si clé connue, sinon retourne icon tel quel (SVG custom)
25
+ */
26
+ public get(icon: string): string | null {
27
+ this.logger.trace('get', icon);
28
+ if (!icon) return null;
29
+ return SvgService.ICONS[icon] ?? icon;
30
+ }
31
+
32
+ public has(key: string): boolean {
33
+ return key in SvgService.ICONS;
34
+ }
35
+ }
@@ -0,0 +1,39 @@
1
+ import {DI, IEventAggregator, ILogger, INode, IPlatform, resolve} from "aurelia";
2
+
3
+ export interface ITransitionService extends TransitionService { }
4
+ export const ITransitionService = /*@__PURE__*/DI.createInterface<ITransitionService>('ITransitionService', (x) => x.singleton(TransitionService));
5
+
6
+ export type TransitionCallback = (e: HTMLElement|HTMLDialogElement) => void
7
+ export class TransitionService
8
+ {
9
+ public securityTimeout: number = 2000;
10
+ public constructor(
11
+ private readonly logger: ILogger = resolve(ILogger).scopeTo('TransitionService'),
12
+ private readonly platform:IPlatform = resolve(IPlatform),
13
+ ) {
14
+ this.logger.trace('constructor')
15
+ }
16
+
17
+ public run(element: HTMLElement, before: TransitionCallback, after?: TransitionCallback) {
18
+ let securityTimeout: any = undefined;
19
+ const endTransition = (evt: TransitionEvent) => {
20
+ if (securityTimeout !== undefined) {
21
+ this.platform.clearTimeout(securityTimeout);
22
+ securityTimeout = undefined;
23
+ }
24
+ element.removeEventListener('transitionend', endTransition);
25
+ if (after) {
26
+ this.logger.trace('after()');
27
+ after(element);
28
+ }
29
+ }
30
+ if (before) {
31
+ securityTimeout = this.platform.setTimeout(endTransition, this.securityTimeout);
32
+ element.addEventListener('transitionend', endTransition);
33
+ this.platform.requestAnimationFrame(() => {
34
+ this.logger.trace('before()');
35
+ before(element);
36
+ });
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,213 @@
1
+ import {DI, ILogger, IPlatform, resolve} from "aurelia";
2
+
3
+ export interface ITrapFocusService extends TrapFocusService { }
4
+ export const ITrapFocusService = /*@__PURE__*/DI.createInterface<ITrapFocusService>('ITrapFocusService', (x) => x.transient(TrapFocusService));
5
+
6
+ export class TrapFocusService
7
+ {
8
+
9
+ public focusableElementsQuerySelector = '[href], button, input, select, textarea, [tabindex]:not([tabindex="-1"]), [accesskey], summary, canvas, audio, video, details, iframe, [contenteditable]';
10
+
11
+ private opener: HTMLElement|null = null;
12
+ private target: HTMLElement|null = null;
13
+ private globalElement: HTMLElement|null = null;
14
+ private startCallback: Function|null = null;
15
+ private stopCallback: Function|null = null;
16
+ private focusableElements: HTMLElement[] = [];
17
+ private lastFocusedElement: HTMLElement|null = null;
18
+ private started: boolean = false;
19
+
20
+
21
+ public constructor(
22
+ private readonly logger: ILogger = resolve(ILogger).scopeTo('TrapFocusService'),
23
+ private readonly platform:IPlatform = resolve(IPlatform),
24
+ ) {
25
+ this.logger.trace('constructor')
26
+ }
27
+
28
+ private buildFocusableElements() {
29
+ this.focusableElements = [];
30
+ const focusableElements = this.target?.querySelectorAll(this.focusableElementsQuerySelector);
31
+ focusableElements?.forEach((element: Element) => {
32
+ const isDisabled = element.hasAttribute('disabled');
33
+ const isAriaHidden = (element.getAttribute('aria-hidden') === 'true');
34
+ const isNotTabbable = (element.getAttribute('tabindex') === '-1');
35
+ if (isDisabled === false && isAriaHidden === false && isNotTabbable === false) {
36
+ this.focusableElements.push(element as HTMLElement);
37
+ }
38
+ });
39
+ }
40
+
41
+ public start(opener: HTMLElement, target: HTMLElement, globalElement: HTMLElement, startCallback?: Function, stopCallback?: Function, initialFocusElement?: HTMLElement) {
42
+ this.logger.trace('start', opener, target);
43
+ this.startCallback = startCallback ?? null;
44
+ this.stopCallback = stopCallback ?? null;
45
+ this.opener = opener;
46
+ this.target = target;
47
+ this.globalElement = globalElement;
48
+ this.buildFocusableElements();
49
+
50
+ // Use provided initialFocusElement if valid, otherwise default to first focusable
51
+ if (initialFocusElement && this.focusableElements.includes(initialFocusElement)) {
52
+ this.lastFocusedElement = initialFocusElement;
53
+ } else {
54
+ this.lastFocusedElement = this.focusableElements[0] || undefined;
55
+ }
56
+
57
+ this.logger.trace('start: add keydown listener');
58
+ this.platform.requestAnimationFrame(() => {
59
+ this.logger.trace('start: focus initial element', this.lastFocusedElement);
60
+ this.lastFocusedElement?.focus();
61
+
62
+ });
63
+ this.target.addEventListener('keydown', this.onKeyDown);
64
+ this.platform.document.addEventListener('click', this.onClickOutside);
65
+ this.started = true;
66
+ if(this.startCallback) {
67
+ const promise = this.startCallback();
68
+ if (promise && promise instanceof Promise) {
69
+ return promise;
70
+ }
71
+ }
72
+ return Promise.resolve();
73
+
74
+ }
75
+ public stop() {
76
+ this.logger.trace('stop');
77
+ return new Promise((resolve, reject) => {
78
+
79
+ if (this.started) {
80
+ this.logger.trace('stop: remove keydown listener');
81
+ this.target?.removeEventListener('keydown', this.onKeyDown);
82
+ this.platform.document.removeEventListener('click', this.onClickOutside);
83
+
84
+ if(this.stopCallback) {
85
+ const promise = this.stopCallback();
86
+ if (promise && promise instanceof Promise) {
87
+ this.platform.requestAnimationFrame(() => {
88
+ this.opener?.focus()
89
+ this.cleanup();
90
+ promise.then((res) => {
91
+ return resolve(res);
92
+ });
93
+ });
94
+ return;
95
+ }
96
+ return resolve(void 0);
97
+ }
98
+
99
+ this.platform.requestAnimationFrame(() => {
100
+ this.opener?.focus()
101
+ this.cleanup();
102
+ return resolve(void 0);
103
+ });
104
+ return;
105
+ }
106
+
107
+ return reject('TrapFocusService: not started');
108
+ });
109
+ }
110
+ private cleanup() {
111
+ this.logger.trace('cleanup');
112
+ if (this.started) {
113
+ this.opener = null;
114
+ this.startCallback = null;
115
+ this.stopCallback = null;
116
+ this.target = null;
117
+ this.lastFocusedElement = null;
118
+ this.focusableElements = [];
119
+ this.started = false;
120
+ }
121
+ }
122
+
123
+
124
+ private focusedElementIndex() : number {
125
+ let index = -1;
126
+ if (this.lastFocusedElement) {
127
+ index = this.focusableElements.indexOf(this.lastFocusedElement);
128
+ }
129
+ if (index === -1 && this.lastFocusedElement !== undefined) {
130
+ this.lastFocusedElement = null;
131
+ }
132
+ return index;
133
+ }
134
+ private focusPreviousElement(loop = true): HTMLElement | null {
135
+
136
+ const currentIndex = this.focusedElementIndex();
137
+ if (currentIndex === -1) {
138
+ return null;
139
+ }
140
+ let changed = false;
141
+ if (currentIndex === 0 && loop === true) {
142
+ this.lastFocusedElement = this.focusableElements[this.focusableElements.length - 1];
143
+ changed = true;
144
+ } else if (currentIndex > 0) {
145
+ this.lastFocusedElement = this.focusableElements[currentIndex - 1];
146
+ changed = true;
147
+ }
148
+ if (changed === true) {
149
+ this.platform.requestAnimationFrame(() => {
150
+ this.logger.trace('focusPreviousElement: focusing', this.lastFocusedElement);
151
+ this.lastFocusedElement?.focus();
152
+ });
153
+ }
154
+ return this.lastFocusedElement;
155
+ }
156
+ private focusNextElement(loop = true): HTMLElement | null {
157
+ const currentIndex = this.focusedElementIndex();
158
+ if (currentIndex === -1) {
159
+ return null;
160
+ }
161
+ let changed = false;
162
+ if (currentIndex === this.focusableElements.length - 1 && loop === true) {
163
+ this.lastFocusedElement = this.focusableElements[0];
164
+ changed = true;
165
+ } else if (currentIndex < this.focusableElements.length - 1) {
166
+ this.lastFocusedElement = this.focusableElements[currentIndex + 1];
167
+ changed = true;
168
+ }
169
+ if (changed === true) {
170
+ this.platform.requestAnimationFrame(() => {
171
+ this.logger.trace('focusNextElement: focusing', this.lastFocusedElement);
172
+ this.lastFocusedElement?.focus();
173
+ });
174
+ }
175
+ return this.lastFocusedElement;
176
+ }
177
+
178
+ private onKeyDown = (event: KeyboardEvent) => {
179
+ let changeFocus = false;
180
+ if (event.key === 'Tab') {
181
+ if (event.shiftKey) {
182
+ // shift + tab loop backwards
183
+ event.preventDefault();
184
+ this.lastFocusedElement = this.focusPreviousElement(true);
185
+ } else {
186
+ // tab loop forwards
187
+ event.preventDefault();
188
+ this.lastFocusedElement = this.focusNextElement(true);
189
+ }
190
+ } else if (event.key === 'ArrowUp') {
191
+ // up arrow, no loop
192
+ event.preventDefault();
193
+ this.lastFocusedElement = this.focusPreviousElement(false);
194
+ } else if (event.key === 'ArrowDown') {
195
+ // down arrow, no loop
196
+ event.preventDefault();
197
+ this.lastFocusedElement = this.focusNextElement(false);
198
+ } else if (event.key === 'Escape') {
199
+ // stop trap focus
200
+ event.preventDefault();
201
+ this.stop();
202
+ }
203
+ };
204
+ private onClickOutside = (event: MouseEvent) => {
205
+ this.logger.trace('onClickOutside', event);
206
+ if (this.started && this.globalElement && event.target) {
207
+ this.logger.trace('onClickOutside: checking if click is outside globalElement', event.target, this.globalElement);
208
+ if (!this.globalElement.contains(event.target as Node)) {
209
+ this.stop();
210
+ }
211
+ }
212
+ }
213
+ }
@@ -0,0 +1,4 @@
1
+ declare module '*.css' {
2
+ const value: string;
3
+ export default value;
4
+ }
@@ -0,0 +1,12 @@
1
+ declare module '*.html' {
2
+ import { IContainer } from '@aurelia/kernel';
3
+ import { BindableDefinition } from '@aurelia/runtime';
4
+ export const name: string;
5
+ export const template: string;
6
+ export default template;
7
+ export const dependencies: string[];
8
+ export const containerless: boolean | undefined;
9
+ export const bindables: Record<string, BindableDefinition>;
10
+ export const shadowOptions: { mode: 'open' | 'closed'} | undefined;
11
+ export function register(container: IContainer);
12
+ }
@@ -0,0 +1,4 @@
1
+ declare module '*.svg' {
2
+ const value: string;
3
+ export default value;
4
+ }