@aurelia-ui-toolkits/headless 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 (284) hide show
  1. package/dist/alert/ui-alert.html +19 -0
  2. package/dist/alert/ui-alert.js +67 -0
  3. package/dist/alert/ui-alert.js.map +1 -0
  4. package/dist/alert-service/alert-configuration.js +11 -0
  5. package/dist/alert-service/alert-configuration.js.map +1 -0
  6. package/dist/alert-service/alert-modal/alert-modal.html +12 -0
  7. package/dist/alert-service/alert-modal/alert-modal.js +31 -0
  8. package/dist/alert-service/alert-modal/alert-modal.js.map +1 -0
  9. package/dist/alert-service/alert-modal/i-alert-modal-payload.js +2 -0
  10. package/dist/alert-service/alert-modal/i-alert-modal-payload.js.map +1 -0
  11. package/dist/alert-service/alert-service.js +108 -0
  12. package/dist/alert-service/alert-service.js.map +1 -0
  13. package/dist/alert-service/decorators/confirm-action.js +14 -0
  14. package/dist/alert-service/decorators/confirm-action.js.map +1 -0
  15. package/dist/alert-service/decorators/using-progress.js +23 -0
  16. package/dist/alert-service/decorators/using-progress.js.map +1 -0
  17. package/dist/alert-service/exceptions-tracker.js +4 -0
  18. package/dist/alert-service/exceptions-tracker.js.map +1 -0
  19. package/dist/alert-service/prompt-dialog/prompt-dialog.html +13 -0
  20. package/dist/alert-service/prompt-dialog/prompt-dialog.js +39 -0
  21. package/dist/alert-service/prompt-dialog/prompt-dialog.js.map +1 -0
  22. package/dist/badge/ui-badge.html +6 -0
  23. package/dist/badge/ui-badge.js +44 -0
  24. package/dist/badge/ui-badge.js.map +1 -0
  25. package/dist/base/boolean-attr.js +4 -0
  26. package/dist/base/boolean-attr.js.map +1 -0
  27. package/dist/base/i-validated-element.js +2 -0
  28. package/dist/base/i-validated-element.js.map +1 -0
  29. package/dist/base/keys.js +14 -0
  30. package/dist/base/keys.js.map +1 -0
  31. package/dist/breadcrumbs/ui-breadcrumbs.html +10 -0
  32. package/dist/breadcrumbs/ui-breadcrumbs.js +31 -0
  33. package/dist/breadcrumbs/ui-breadcrumbs.js.map +1 -0
  34. package/dist/button/enhance-ui-button.js +25 -0
  35. package/dist/button/enhance-ui-button.js.map +1 -0
  36. package/dist/button/ui-button.html +20 -0
  37. package/dist/button/ui-button.js +77 -0
  38. package/dist/button/ui-button.js.map +1 -0
  39. package/dist/button/ui-icon-button.html +20 -0
  40. package/dist/button/ui-icon-button.js +77 -0
  41. package/dist/button/ui-icon-button.js.map +1 -0
  42. package/dist/checkbox/ui-checkbox.html +32 -0
  43. package/dist/checkbox/ui-checkbox.js +186 -0
  44. package/dist/checkbox/ui-checkbox.js.map +1 -0
  45. package/dist/chip/ui-chip.html +32 -0
  46. package/dist/chip/ui-chip.js +129 -0
  47. package/dist/chip/ui-chip.js.map +1 -0
  48. package/dist/combobox/enhance-ui-combobox.js +26 -0
  49. package/dist/combobox/enhance-ui-combobox.js.map +1 -0
  50. package/dist/combobox/ui-combobox.html +76 -0
  51. package/dist/combobox/ui-combobox.js +478 -0
  52. package/dist/combobox/ui-combobox.js.map +1 -0
  53. package/dist/disclosure/ui-disclosure.html +28 -0
  54. package/dist/disclosure/ui-disclosure.js +75 -0
  55. package/dist/disclosure/ui-disclosure.js.map +1 -0
  56. package/dist/drawer/ui-drawer.html +35 -0
  57. package/dist/drawer/ui-drawer.js +246 -0
  58. package/dist/drawer/ui-drawer.js.map +1 -0
  59. package/dist/index.js +135 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/input/enhance-ui-input.js +26 -0
  62. package/dist/input/enhance-ui-input.js.map +1 -0
  63. package/dist/input/ui-input.html +56 -0
  64. package/dist/input/ui-input.js +259 -0
  65. package/dist/input/ui-input.js.map +1 -0
  66. package/dist/list/ui-list-item.html +22 -0
  67. package/dist/list/ui-list-item.js +59 -0
  68. package/dist/list/ui-list-item.js.map +1 -0
  69. package/dist/list/ui-list.html +10 -0
  70. package/dist/list/ui-list.js +316 -0
  71. package/dist/list/ui-list.js.map +1 -0
  72. package/dist/menu/ui-menu.html +20 -0
  73. package/dist/menu/ui-menu.js +154 -0
  74. package/dist/menu/ui-menu.js.map +1 -0
  75. package/dist/popup/ui-popup.html +16 -0
  76. package/dist/popup/ui-popup.js +397 -0
  77. package/dist/popup/ui-popup.js.map +1 -0
  78. package/dist/progress/ui-progress.html +17 -0
  79. package/dist/progress/ui-progress.js +76 -0
  80. package/dist/progress/ui-progress.js.map +1 -0
  81. package/dist/radio/ui-radio-group.html +27 -0
  82. package/dist/radio/ui-radio-group.js +259 -0
  83. package/dist/radio/ui-radio-group.js.map +1 -0
  84. package/dist/radio/ui-radio.html +11 -0
  85. package/dist/radio/ui-radio.js +55 -0
  86. package/dist/radio/ui-radio.js.map +1 -0
  87. package/dist/segmented-control/ui-segment.html +10 -0
  88. package/dist/segmented-control/ui-segment.js +44 -0
  89. package/dist/segmented-control/ui-segment.js.map +1 -0
  90. package/dist/segmented-control/ui-segmented-control.html +9 -0
  91. package/dist/segmented-control/ui-segmented-control.js +134 -0
  92. package/dist/segmented-control/ui-segmented-control.js.map +1 -0
  93. package/dist/select/enhance-ui-select.js +26 -0
  94. package/dist/select/enhance-ui-select.js.map +1 -0
  95. package/dist/select/ui-select.html +70 -0
  96. package/dist/select/ui-select.js +323 -0
  97. package/dist/select/ui-select.js.map +1 -0
  98. package/dist/slider/ui-slider.html +69 -0
  99. package/dist/slider/ui-slider.js +362 -0
  100. package/dist/slider/ui-slider.js.map +1 -0
  101. package/dist/splitter/ui-splitter.html +14 -0
  102. package/dist/splitter/ui-splitter.js +257 -0
  103. package/dist/splitter/ui-splitter.js.map +1 -0
  104. package/dist/switch/ui-switch.html +23 -0
  105. package/dist/switch/ui-switch.js +121 -0
  106. package/dist/switch/ui-switch.js.map +1 -0
  107. package/dist/table/enhance-ui-table.js +25 -0
  108. package/dist/table/enhance-ui-table.js.map +1 -0
  109. package/dist/table/ui-table-column.html +17 -0
  110. package/dist/table/ui-table-column.js +127 -0
  111. package/dist/table/ui-table-column.js.map +1 -0
  112. package/dist/table/ui-table.html +56 -0
  113. package/dist/table/ui-table.js +225 -0
  114. package/dist/table/ui-table.js.map +1 -0
  115. package/dist/tabs/ui-tab.html +10 -0
  116. package/dist/tabs/ui-tab.js +52 -0
  117. package/dist/tabs/ui-tab.js.map +1 -0
  118. package/dist/tabs/ui-tabs.html +3 -0
  119. package/dist/tabs/ui-tabs.js +112 -0
  120. package/dist/tabs/ui-tabs.js.map +1 -0
  121. package/dist/toast/ui-toast-region.html +11 -0
  122. package/dist/toast/ui-toast-region.js +38 -0
  123. package/dist/toast/ui-toast-region.js.map +1 -0
  124. package/dist/toast/ui-toast-service.js +70 -0
  125. package/dist/toast/ui-toast-service.js.map +1 -0
  126. package/dist/tooltip/ui-tooltip-service.js +63 -0
  127. package/dist/tooltip/ui-tooltip-service.js.map +1 -0
  128. package/dist/tooltip/ui-tooltip.js +221 -0
  129. package/dist/tooltip/ui-tooltip.js.map +1 -0
  130. package/dist/top-app-bar/ui-top-app-bar.html +24 -0
  131. package/dist/top-app-bar/ui-top-app-bar.js +68 -0
  132. package/dist/top-app-bar/ui-top-app-bar.js.map +1 -0
  133. package/dist/tree/ui-tree.html +38 -0
  134. package/dist/tree/ui-tree.js +340 -0
  135. package/dist/tree/ui-tree.js.map +1 -0
  136. package/dist/types/alert/ui-alert.d.ts +11 -0
  137. package/dist/types/alert-service/alert-configuration.d.ts +8 -0
  138. package/dist/types/alert-service/alert-modal/alert-modal.d.ts +7 -0
  139. package/dist/types/alert-service/alert-modal/i-alert-modal-payload.d.ts +14 -0
  140. package/dist/types/alert-service/alert-service.d.ts +17 -0
  141. package/dist/types/alert-service/decorators/confirm-action.d.ts +3 -0
  142. package/dist/types/alert-service/decorators/using-progress.d.ts +6 -0
  143. package/dist/types/alert-service/exceptions-tracker.d.ts +3 -0
  144. package/dist/types/alert-service/prompt-dialog/prompt-dialog.d.ts +17 -0
  145. package/dist/types/badge/ui-badge.d.ts +7 -0
  146. package/dist/types/base/boolean-attr.d.ts +1 -0
  147. package/dist/types/base/i-validated-element.d.ts +10 -0
  148. package/dist/types/base/keys.d.ts +12 -0
  149. package/dist/types/breadcrumbs/ui-breadcrumbs.d.ts +8 -0
  150. package/dist/types/button/enhance-ui-button.d.ts +3 -0
  151. package/dist/types/button/ui-button.d.ts +16 -0
  152. package/dist/types/button/ui-icon-button.d.ts +18 -0
  153. package/dist/types/checkbox/ui-checkbox.d.ts +32 -0
  154. package/dist/types/chip/ui-chip.d.ts +26 -0
  155. package/dist/types/combobox/enhance-ui-combobox.d.ts +3 -0
  156. package/dist/types/combobox/ui-combobox.d.ts +79 -0
  157. package/dist/types/disclosure/ui-disclosure.d.ts +18 -0
  158. package/dist/types/drawer/ui-drawer.d.ts +38 -0
  159. package/dist/types/index.d.ts +91 -0
  160. package/dist/types/input/enhance-ui-input.d.ts +3 -0
  161. package/dist/types/input/ui-input.d.ts +44 -0
  162. package/dist/types/list/ui-list-item.d.ts +10 -0
  163. package/dist/types/list/ui-list.d.ts +45 -0
  164. package/dist/types/menu/ui-menu.d.ts +29 -0
  165. package/dist/types/popup/ui-popup.d.ts +61 -0
  166. package/dist/types/progress/ui-progress.d.ts +15 -0
  167. package/dist/types/radio/ui-radio-group.d.ts +37 -0
  168. package/dist/types/radio/ui-radio.d.ts +11 -0
  169. package/dist/types/segmented-control/ui-segment.d.ts +8 -0
  170. package/dist/types/segmented-control/ui-segmented-control.d.ts +17 -0
  171. package/dist/types/select/enhance-ui-select.d.ts +3 -0
  172. package/dist/types/select/ui-select.d.ts +50 -0
  173. package/dist/types/slider/ui-slider.d.ts +58 -0
  174. package/dist/types/splitter/ui-splitter.d.ts +39 -0
  175. package/dist/types/switch/ui-switch.d.ts +23 -0
  176. package/dist/types/table/enhance-ui-table.d.ts +3 -0
  177. package/dist/types/table/ui-table-column.d.ts +22 -0
  178. package/dist/types/table/ui-table.d.ts +51 -0
  179. package/dist/types/tabs/ui-tab.d.ts +10 -0
  180. package/dist/types/tabs/ui-tabs.d.ts +16 -0
  181. package/dist/types/toast/ui-toast-region.d.ts +6 -0
  182. package/dist/types/toast/ui-toast-service.d.ts +28 -0
  183. package/dist/types/tooltip/ui-tooltip-service.d.ts +23 -0
  184. package/dist/types/tooltip/ui-tooltip.d.ts +35 -0
  185. package/dist/types/top-app-bar/ui-top-app-bar.d.ts +9 -0
  186. package/dist/types/tree/ui-tree.d.ts +70 -0
  187. package/dist/types/validation/ui-validation-controller-factory.d.ts +7 -0
  188. package/dist/types/validation/ui-validation-result-presenter.d.ts +4 -0
  189. package/dist/types/validation/validate.d.ts +13 -0
  190. package/dist/validation/ui-validation-controller-factory.js +17 -0
  191. package/dist/validation/ui-validation-controller-factory.js.map +1 -0
  192. package/dist/validation/ui-validation-result-presenter.js +23 -0
  193. package/dist/validation/ui-validation-result-presenter.js.map +1 -0
  194. package/dist/validation/validate.js +24 -0
  195. package/dist/validation/validate.js.map +1 -0
  196. package/package.json +50 -0
  197. package/src/alert/ui-alert.html +19 -0
  198. package/src/alert/ui-alert.ts +33 -0
  199. package/src/alert-service/alert-configuration.ts +11 -0
  200. package/src/alert-service/alert-modal/alert-modal.html +12 -0
  201. package/src/alert-service/alert-modal/alert-modal.ts +19 -0
  202. package/src/alert-service/alert-modal/i-alert-modal-payload.ts +14 -0
  203. package/src/alert-service/alert-service.ts +116 -0
  204. package/src/alert-service/decorators/confirm-action.ts +18 -0
  205. package/src/alert-service/decorators/using-progress.ts +32 -0
  206. package/src/alert-service/exceptions-tracker.ts +3 -0
  207. package/src/alert-service/prompt-dialog/prompt-dialog.html +13 -0
  208. package/src/alert-service/prompt-dialog/prompt-dialog.ts +37 -0
  209. package/src/badge/ui-badge.html +6 -0
  210. package/src/badge/ui-badge.ts +17 -0
  211. package/src/base/boolean-attr.ts +3 -0
  212. package/src/base/i-validated-element.ts +11 -0
  213. package/src/base/keys.ts +12 -0
  214. package/src/breadcrumbs/ui-breadcrumbs.html +10 -0
  215. package/src/breadcrumbs/ui-breadcrumbs.ts +14 -0
  216. package/src/button/enhance-ui-button.ts +9 -0
  217. package/src/button/ui-button.html +20 -0
  218. package/src/button/ui-button.ts +60 -0
  219. package/src/button/ui-icon-button.html +20 -0
  220. package/src/button/ui-icon-button.ts +62 -0
  221. package/src/checkbox/ui-checkbox.html +32 -0
  222. package/src/checkbox/ui-checkbox.ts +188 -0
  223. package/src/chip/ui-chip.html +32 -0
  224. package/src/chip/ui-chip.ts +118 -0
  225. package/src/combobox/enhance-ui-combobox.ts +10 -0
  226. package/src/combobox/ui-combobox.html +76 -0
  227. package/src/combobox/ui-combobox.ts +450 -0
  228. package/src/disclosure/ui-disclosure.html +28 -0
  229. package/src/disclosure/ui-disclosure.ts +68 -0
  230. package/src/drawer/ui-drawer.html +35 -0
  231. package/src/drawer/ui-drawer.ts +219 -0
  232. package/src/index.ts +152 -0
  233. package/src/input/enhance-ui-input.ts +10 -0
  234. package/src/input/ui-input.html +56 -0
  235. package/src/input/ui-input.ts +225 -0
  236. package/src/list/ui-list-item.html +22 -0
  237. package/src/list/ui-list-item.ts +25 -0
  238. package/src/list/ui-list.html +10 -0
  239. package/src/list/ui-list.ts +330 -0
  240. package/src/menu/ui-menu.html +20 -0
  241. package/src/menu/ui-menu.ts +103 -0
  242. package/src/popup/ui-popup.html +16 -0
  243. package/src/popup/ui-popup.ts +391 -0
  244. package/src/progress/ui-progress.html +17 -0
  245. package/src/progress/ui-progress.ts +51 -0
  246. package/src/radio/ui-radio-group.html +27 -0
  247. package/src/radio/ui-radio-group.ts +250 -0
  248. package/src/radio/ui-radio.html +11 -0
  249. package/src/radio/ui-radio.ts +35 -0
  250. package/src/resource.d.ts +4 -0
  251. package/src/segmented-control/ui-segment.html +10 -0
  252. package/src/segmented-control/ui-segment.ts +20 -0
  253. package/src/segmented-control/ui-segmented-control.html +9 -0
  254. package/src/segmented-control/ui-segmented-control.ts +119 -0
  255. package/src/select/enhance-ui-select.ts +10 -0
  256. package/src/select/ui-select.html +70 -0
  257. package/src/select/ui-select.ts +294 -0
  258. package/src/slider/ui-slider.html +69 -0
  259. package/src/slider/ui-slider.ts +329 -0
  260. package/src/splitter/ui-splitter.html +14 -0
  261. package/src/splitter/ui-splitter.ts +249 -0
  262. package/src/switch/ui-switch.html +23 -0
  263. package/src/switch/ui-switch.ts +121 -0
  264. package/src/table/enhance-ui-table.ts +9 -0
  265. package/src/table/ui-table-column.html +17 -0
  266. package/src/table/ui-table-column.ts +108 -0
  267. package/src/table/ui-table.html +56 -0
  268. package/src/table/ui-table.ts +209 -0
  269. package/src/tabs/ui-tab.html +10 -0
  270. package/src/tabs/ui-tab.ts +30 -0
  271. package/src/tabs/ui-tabs.html +3 -0
  272. package/src/tabs/ui-tabs.ts +105 -0
  273. package/src/toast/ui-toast-region.html +11 -0
  274. package/src/toast/ui-toast-region.ts +18 -0
  275. package/src/toast/ui-toast-service.ts +100 -0
  276. package/src/tooltip/ui-tooltip-service.ts +84 -0
  277. package/src/tooltip/ui-tooltip.ts +200 -0
  278. package/src/top-app-bar/ui-top-app-bar.html +24 -0
  279. package/src/top-app-bar/ui-top-app-bar.ts +27 -0
  280. package/src/tree/ui-tree.html +38 -0
  281. package/src/tree/ui-tree.ts +363 -0
  282. package/src/validation/ui-validation-controller-factory.ts +20 -0
  283. package/src/validation/ui-validation-result-presenter.ts +26 -0
  284. package/src/validation/validate.ts +35 -0
@@ -0,0 +1,249 @@
1
+ import { bindable, BindingMode, customElement, INode, resolve } from 'aurelia';
2
+ import { booleanAttr } from '../base/boolean-attr';
3
+ import { Keys } from '../base/keys';
4
+ import template from './ui-splitter.html?raw';
5
+
6
+ type SplitterDirection = 'horizontal' | 'vertical';
7
+
8
+ @customElement({ name: 'ui-splitter', template })
9
+ export class UiSplitter implements EventListenerObject {
10
+ private readonly host = resolve(INode) as HTMLElement;
11
+ private targetElement: HTMLElement | undefined;
12
+ private startPosition = 0;
13
+ private startSize = 0;
14
+ private dragging = false;
15
+ private pointerMoved = false;
16
+ private expandedSize = 240;
17
+ private targetDisplay = '';
18
+ private targetOverflow = '';
19
+
20
+ @bindable({ mode: BindingMode.twoWay })
21
+ size: number = 240;
22
+ sizeChanged(): void {
23
+ this.applySize();
24
+ this.updateValueNow();
25
+ }
26
+
27
+ @bindable
28
+ direction: SplitterDirection = 'horizontal';
29
+ directionChanged(): void {
30
+ this.applySize();
31
+ }
32
+
33
+ @bindable
34
+ min: number = 80;
35
+
36
+ @bindable
37
+ max: number = 800;
38
+
39
+ @bindable({ set: booleanAttr })
40
+ disabled: boolean = false;
41
+
42
+ @bindable
43
+ storageKey: string | undefined;
44
+
45
+ valueNow = 240;
46
+
47
+ attaching(): void {
48
+ this.targetElement = this.host.previousElementSibling instanceof HTMLElement
49
+ ? this.host.previousElementSibling
50
+ : undefined;
51
+ this.targetDisplay = this.targetElement?.style.display ?? '';
52
+ this.targetOverflow = this.targetElement?.style.overflow ?? '';
53
+ this.expandedSize = this.size;
54
+ this.loadSize();
55
+ this.applySize();
56
+ this.updateValueNow();
57
+ }
58
+
59
+ detaching(): void {
60
+ this.stopDragging();
61
+ }
62
+
63
+ handleEvent(event: Event): void {
64
+ if (event.type === 'pointermove') {
65
+ this.onPointerMove(event as PointerEvent);
66
+ return;
67
+ }
68
+
69
+ if (event.type === 'pointerup') {
70
+ this.onPointerUp();
71
+ }
72
+ }
73
+
74
+ onPointerDown(event: PointerEvent): void {
75
+ if (this.disabled || !this.targetElement) {
76
+ return;
77
+ }
78
+
79
+ event.preventDefault();
80
+ this.dragging = true;
81
+ this.pointerMoved = false;
82
+ this.startPosition = this.direction === 'horizontal' ? event.clientX : event.clientY;
83
+ this.startSize = this.size;
84
+ this.host.setPointerCapture(event.pointerId);
85
+ window.addEventListener('pointermove', this);
86
+ window.addEventListener('pointerup', this);
87
+ }
88
+
89
+ onKeyDown(event: KeyboardEvent): void {
90
+ if (this.disabled) {
91
+ return;
92
+ }
93
+
94
+ const largeStep = event.shiftKey ? 50 : 10;
95
+ if (this.direction === 'horizontal') {
96
+ if (event.key === Keys.ArrowLeft) {
97
+ event.preventDefault();
98
+ this.setSize(this.size - largeStep, true);
99
+ return;
100
+ }
101
+ if (event.key === Keys.ArrowRight) {
102
+ event.preventDefault();
103
+ this.setSize(this.size + largeStep, true);
104
+ return;
105
+ }
106
+ } else {
107
+ if (event.key === Keys.ArrowUp) {
108
+ event.preventDefault();
109
+ this.setSize(this.size - largeStep, true);
110
+ return;
111
+ }
112
+ if (event.key === Keys.ArrowDown) {
113
+ event.preventDefault();
114
+ this.setSize(this.size + largeStep, true);
115
+ return;
116
+ }
117
+ }
118
+
119
+ if (event.key === Keys.Home) {
120
+ event.preventDefault();
121
+ this.setSize(this.minSize, true);
122
+ return;
123
+ }
124
+
125
+ if (event.key === Keys.End) {
126
+ event.preventDefault();
127
+ this.setSize(this.maxSize, true);
128
+ }
129
+ }
130
+
131
+ private onPointerMove(event: PointerEvent): void {
132
+ if (!this.dragging) {
133
+ return;
134
+ }
135
+
136
+ const position = this.direction === 'horizontal' ? event.clientX : event.clientY;
137
+ this.pointerMoved ||= Math.abs(position - this.startPosition) > 3;
138
+ this.setSize(this.startSize + position - this.startPosition);
139
+ }
140
+
141
+ private onPointerUp(): void {
142
+ if (!this.dragging) {
143
+ return;
144
+ }
145
+
146
+ this.stopDragging();
147
+ if (!this.pointerMoved) {
148
+ this.toggleCollapsed();
149
+ return;
150
+ }
151
+ this.persistSize();
152
+ }
153
+
154
+ private stopDragging(): void {
155
+ this.dragging = false;
156
+ window.removeEventListener('pointermove', this);
157
+ window.removeEventListener('pointerup', this);
158
+ }
159
+
160
+ private setSize(size: number, persist = false): void {
161
+ this.size = Math.max(this.minSize, Math.min(this.maxSize, Number(size) || this.minSize));
162
+ this.expandedSize = this.size;
163
+ this.applySize();
164
+ this.updateValueNow();
165
+ if (persist) {
166
+ this.persistSize();
167
+ }
168
+ }
169
+
170
+ private toggleCollapsed(): void {
171
+ if (this.size <= 0) {
172
+ this.size = Math.max(this.minSize, Math.min(this.maxSize, this.expandedSize || this.minSize));
173
+ } else {
174
+ this.expandedSize = this.size;
175
+ this.size = 0;
176
+ }
177
+ this.applySize();
178
+ this.updateValueNow();
179
+ this.persistSize();
180
+ }
181
+
182
+ private applySize(): void {
183
+ if (!this.targetElement) {
184
+ return;
185
+ }
186
+
187
+ const sizeValue = Math.max(0, Number(this.size) || 0);
188
+ const size = `${sizeValue}px`;
189
+ this.targetElement.style.display = sizeValue === 0 ? 'none' : this.targetDisplay;
190
+ this.targetElement.style.flexGrow = '0';
191
+ this.targetElement.style.flexShrink = '0';
192
+ this.targetElement.style.overflow = sizeValue === 0 ? 'hidden' : this.targetOverflow;
193
+ if (this.direction === 'horizontal') {
194
+ this.targetElement.style.width = size;
195
+ this.targetElement.style.flexBasis = size;
196
+ this.targetElement.style.height = '';
197
+ return;
198
+ }
199
+
200
+ this.targetElement.style.height = size;
201
+ this.targetElement.style.flexBasis = size;
202
+ this.targetElement.style.width = '';
203
+ }
204
+ private updateValueNow(): void {
205
+ this.valueNow = Math.max(0, Math.min(this.maxSize, Number(this.size) || 0));
206
+ }
207
+
208
+ private loadSize(): void {
209
+ if (!this.storageKey) {
210
+ return;
211
+ }
212
+
213
+ try {
214
+ const value = localStorage.getItem(this.storageId);
215
+ if (value !== null) {
216
+ this.size = Math.max(0, Math.min(this.maxSize, Number(value) || 0));
217
+ if (this.size > 0) {
218
+ this.expandedSize = this.size;
219
+ }
220
+ }
221
+ } catch {
222
+ // Ignore unavailable storage.
223
+ }
224
+ }
225
+
226
+ private persistSize(): void {
227
+ if (!this.storageKey) {
228
+ return;
229
+ }
230
+
231
+ try {
232
+ localStorage.setItem(this.storageId, String(this.size));
233
+ } catch {
234
+ // Ignore unavailable storage.
235
+ }
236
+ }
237
+
238
+ private get minSize(): number {
239
+ return Math.max(0, Number(this.min) || 0);
240
+ }
241
+
242
+ private get maxSize(): number {
243
+ return Math.max(this.minSize, Number(this.max) || this.minSize);
244
+ }
245
+
246
+ private get storageId(): string {
247
+ return `ui-splitter:${this.storageKey}:size`;
248
+ }
249
+ }
@@ -0,0 +1,23 @@
1
+ <template class="ui-switch"
2
+ role="switch"
3
+ tabindex.bind="disabled ? -1 : 0"
4
+ aria-checked.attr="checked ? 'true' : 'false'"
5
+ aria-disabled.attr="disabled ? '' : null"
6
+ data-checked.attr="checked ? '' : null"
7
+ data-disabled.attr="disabled ? '' : null"
8
+ data-hover.attr="hover ? '' : null"
9
+ data-focus.attr="focus ? '' : null"
10
+ data-active.attr="active ? '' : null"
11
+ data-changing.attr="changing ? '' : null"
12
+ click.trigger="onClick()"
13
+ keyup.trigger="onKeyUp($event)"
14
+ keypress.trigger="onKeyPress($event)"
15
+ mouseenter.trigger="onMouseEnter()"
16
+ mouseleave.trigger="onMouseLeave()"
17
+ focusin.trigger="onFocusIn()"
18
+ focusout.trigger="onFocusOut()"
19
+ pointerdown.trigger="onPointerDown()"
20
+ pointerup.trigger="onPointerUp()"
21
+ pointerleave.trigger="onPointerLeave()">
22
+ <span class="ui-switch__thumb" aria-hidden="true"></span>
23
+ </template>
@@ -0,0 +1,121 @@
1
+ import { bindable, BindingMode, customElement, INode, resolve } from 'aurelia';
2
+ import { booleanAttr } from '../base/boolean-attr';
3
+ import { Keys } from '../base/keys';
4
+ import template from './ui-switch.html?raw';
5
+
6
+ @customElement({ name: 'ui-switch', template })
7
+ export class UiSwitch {
8
+ private readonly host = resolve(INode) as HTMLElement;
9
+
10
+ @bindable({ mode: BindingMode.twoWay, set: booleanAttr })
11
+ checked: boolean = false;
12
+
13
+ @bindable({ set: booleanAttr })
14
+ disabled: boolean = false;
15
+
16
+ hover: boolean = false;
17
+ focus: boolean = false;
18
+ active: boolean = false;
19
+ changing: boolean = false;
20
+
21
+ private changingFrame: number | undefined;
22
+
23
+ onClick(): void {
24
+ this.toggle();
25
+ }
26
+
27
+ onKeyUp(event: KeyboardEvent): void {
28
+ if (event.key === Keys.Space) {
29
+ event.preventDefault();
30
+ this.toggle();
31
+ return;
32
+ }
33
+
34
+ if (event.key === Keys.Enter) {
35
+ this.submitClosestForm(event.currentTarget);
36
+ }
37
+ }
38
+
39
+ onKeyPress(event: KeyboardEvent): void {
40
+ if (event.key === Keys.Space || event.key === Keys.Enter) {
41
+ event.preventDefault();
42
+ }
43
+ }
44
+
45
+ onMouseEnter(): void {
46
+ if (!this.disabled) {
47
+ this.hover = true;
48
+ }
49
+ }
50
+
51
+ onMouseLeave(): void {
52
+ this.hover = false;
53
+ }
54
+
55
+ onFocusIn(): void {
56
+ if (!this.disabled) {
57
+ this.focus = true;
58
+ }
59
+ }
60
+
61
+ onFocusOut(): void {
62
+ this.focus = false;
63
+ }
64
+
65
+ onPointerDown(): void {
66
+ if (!this.disabled) {
67
+ this.active = true;
68
+ }
69
+ }
70
+
71
+ onPointerUp(): void {
72
+ this.active = false;
73
+ }
74
+
75
+ onPointerLeave(): void {
76
+ this.active = false;
77
+ }
78
+
79
+ detaching(): void {
80
+ if (this.changingFrame) {
81
+ cancelAnimationFrame(this.changingFrame);
82
+ this.changingFrame = undefined;
83
+ }
84
+ }
85
+
86
+ private toggle(): void {
87
+ if (this.disabled) {
88
+ return;
89
+ }
90
+
91
+ this.changing = true;
92
+ this.checked = !this.checked;
93
+ this.host.dispatchEvent(new Event('input', { bubbles: true }));
94
+ this.host.dispatchEvent(new Event('change', { bubbles: true }));
95
+
96
+ if (this.changingFrame) {
97
+ cancelAnimationFrame(this.changingFrame);
98
+ }
99
+
100
+ this.changingFrame = requestAnimationFrame(() => {
101
+ this.changing = false;
102
+ this.changingFrame = undefined;
103
+ });
104
+ }
105
+
106
+ private submitClosestForm(target: EventTarget | null): void {
107
+ const element = target instanceof HTMLElement ? target : null;
108
+ const form = element?.closest('form');
109
+
110
+ if (!form || this.disabled) {
111
+ return;
112
+ }
113
+
114
+ if (typeof form.requestSubmit === 'function') {
115
+ form.requestSubmit();
116
+ return;
117
+ }
118
+
119
+ form.submit();
120
+ }
121
+ }
@@ -0,0 +1,9 @@
1
+ import { templateCompilerHooks } from 'aurelia';
2
+
3
+ @templateCompilerHooks
4
+ export class EnhanceUiTable {
5
+ compiling(template: HTMLElement | HTMLTemplateElement) {
6
+ template.innerHTML = template.innerHTML.replace(/\sui-table-column="([^"]*)"/g, ' as-element="ui-table-column" id="$1"');
7
+ template.innerHTML = template.innerHTML.replace(/\sui-table-column(?:="")?(?=\s|>)/g, ' as-element="ui-table-column"');
8
+ }
9
+ }
@@ -0,0 +1,17 @@
1
+ <template class="ui-table-column"
2
+ data-sortable.attr="sortable ? '' : null"
3
+ data-resizable.attr="resizable ? '' : null"
4
+ data-sort.attr="direction || ''"
5
+ aria-sort.attr="direction ? (direction === 'asc' ? 'ascending' : 'descending') : null"
6
+ click.trigger="onClick($event)">
7
+ <au-slot></au-slot>
8
+ <span class="ui-table-column__sort-indicator" if.bind="direction" aria-hidden="true">
9
+ <span>${direction === 'asc' ? '↑' : '↓'}</span>
10
+ <span class="ui-table-column__sort-order" if.bind="sortOrder">${sortOrder}</span>
11
+ </span>
12
+ <span class="ui-table-column__resize-handle"
13
+ if.bind="resizable"
14
+ ref="resizeHandle"
15
+ aria-hidden="true"
16
+ pointerdown.trigger="onPointerDown($event)"></span>
17
+ </template>
@@ -0,0 +1,108 @@
1
+ import { bindable, BindingMode, customElement, INode, resolve } from 'aurelia';
2
+ import { booleanAttr } from '../base/boolean-attr';
3
+ import { UiTable } from './ui-table';
4
+ import template from './ui-table-column.html?raw';
5
+
6
+ @customElement({ name: 'ui-table-column', template })
7
+ export class UiTableColumn implements EventListenerObject {
8
+ readonly host = resolve(INode) as HTMLElement;
9
+ readonly table = resolve(UiTable);
10
+ private resizeHandle: HTMLElement | undefined;
11
+ private startX = 0;
12
+ private startWidth = 0;
13
+ private resizing = false;
14
+
15
+ @bindable({ set: booleanAttr })
16
+ sortable: boolean = false;
17
+
18
+ @bindable({ set: booleanAttr })
19
+ resizable: boolean = false;
20
+
21
+ @bindable
22
+ minWidth: number = 64;
23
+
24
+ @bindable({ mode: BindingMode.twoWay })
25
+ direction: 'asc' | 'desc' | undefined;
26
+
27
+ @bindable
28
+ sortOrder: number | undefined;
29
+
30
+ attaching(): void {
31
+ this.applyWidth(this.table.getColumnWidth(this.host.id));
32
+ }
33
+
34
+ detaching(): void {
35
+ window.removeEventListener('pointermove', this);
36
+ window.removeEventListener('pointerup', this);
37
+ }
38
+
39
+ handleEvent(event: Event): void {
40
+ if (event.type === 'pointermove') {
41
+ this.onPointerMove(event as PointerEvent);
42
+ return;
43
+ }
44
+
45
+ if (event.type === 'pointerup') {
46
+ this.onPointerUp();
47
+ }
48
+ }
49
+
50
+ applyWidth(width: number | undefined): void {
51
+ if (width === undefined) {
52
+ this.host.style.removeProperty('width');
53
+ this.host.style.removeProperty('min-width');
54
+ return;
55
+ }
56
+
57
+ this.host.style.width = `${width}px`;
58
+ this.host.style.minWidth = `${width}px`;
59
+ }
60
+
61
+ onClick(event: MouseEvent): void {
62
+ if (!this.sortable || this.resizing || this.resizeHandle?.contains(event.target as Node | null)) {
63
+ return;
64
+ }
65
+
66
+ const direction = !this.direction ? 'asc' : this.direction === 'asc' ? 'desc' : undefined;
67
+
68
+ this.host.dispatchEvent(new CustomEvent('column-sort', {
69
+ bubbles: true,
70
+ detail: { column: this.host.id, columnViewModel: this, direction, multiple: event.ctrlKey }
71
+ }));
72
+ }
73
+
74
+ onPointerDown(event: PointerEvent): void {
75
+ if (!this.resizable) {
76
+ return;
77
+ }
78
+
79
+ event.preventDefault();
80
+ event.stopPropagation();
81
+ this.resizing = true;
82
+ this.startX = event.clientX;
83
+ this.startWidth = this.host.getBoundingClientRect().width;
84
+ this.resizeHandle?.setPointerCapture(event.pointerId);
85
+ window.addEventListener('pointermove', this);
86
+ window.addEventListener('pointerup', this);
87
+ }
88
+
89
+ private onPointerMove(event: PointerEvent): void {
90
+ if (!this.resizing) {
91
+ return;
92
+ }
93
+
94
+ const width = Math.max(Number(this.minWidth) || 64, this.startWidth + event.clientX - this.startX);
95
+ this.table.setColumnWidth(this.host.id, width);
96
+ }
97
+
98
+ private onPointerUp(): void {
99
+ if (!this.resizing) {
100
+ return;
101
+ }
102
+
103
+ this.resizing = false;
104
+ window.removeEventListener('pointermove', this);
105
+ window.removeEventListener('pointerup', this);
106
+ this.table.setColumnWidth(this.host.id, this.host.getBoundingClientRect().width, true);
107
+ }
108
+ }
@@ -0,0 +1,56 @@
1
+ <template class="ui-table"
2
+ column-sort.trigger="onColumnSort($event)"
3
+ aria-busy.attr="progress ? 'true' : null"
4
+ aria-disabled.attr="progress ? 'true' : null"
5
+ data-disabled.attr="progress ? '' : null"
6
+ data-progress.attr="progress ? '' : null">
7
+ <ui-progress class="ui-table__progress" if.bind="progress" label="Loading table"></ui-progress>
8
+ <au-slot></au-slot>
9
+ <div class="ui-table__pagination" if.bind="pagination">
10
+ <div class="ui-table__page-size">
11
+ <span class="ui-table__page-size-label">Rows per page</span>
12
+ <ui-select class="ui-table__page-size-select"
13
+ value.to-view="pageSize"
14
+ selected-item.to-view="pageSize"
15
+ change.trigger="onPageSizeChange($event)">
16
+ <ui-list items.bind="pageSizeOptions" selected.to-view="pageSize">
17
+ <ui-list-item repeat.for="size of pageSizeOptions" value.bind="size">${size}</ui-list-item>
18
+ </ui-list>
19
+ </ui-select>
20
+ </div>
21
+ <div class="ui-table__page-size">
22
+ <span class="ui-table__page-size-label">Page</span>
23
+ <ui-select class="ui-table__page-select"
24
+ value.to-view="page"
25
+ selected-item.to-view="page"
26
+ change.trigger="onPageChange($event)">
27
+ <ui-list items.bind="pageOptions" selected.to-view="page">
28
+ <ui-list-item repeat.for="pageOption of pageOptions" value.bind="pageOption">${pageOption}</ui-list-item>
29
+ </ui-list>
30
+ </ui-select>
31
+ </div>
32
+ <span class="ui-table__pagination-summary">${paginationText}</span>
33
+ <div class="ui-table__pagination-actions">
34
+ <button ui-icon-button type="button" disabled.bind="page === 1" aria-label="First page" click.trigger="firstPage()">
35
+ <svg class="ui-table__pagination-icon" viewBox="0 0 24 24" aria-hidden="true">
36
+ <path d="M6 5v14M18 6l-6 6 6 6" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path>
37
+ </svg>
38
+ </button>
39
+ <button ui-icon-button type="button" disabled.bind="page === 1" aria-label="Previous page" click.trigger="previousPage()">
40
+ <svg class="ui-table__pagination-icon" viewBox="0 0 24 24" aria-hidden="true">
41
+ <path d="M15 6l-6 6 6 6" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path>
42
+ </svg>
43
+ </button>
44
+ <button ui-icon-button type="button" disabled.bind="page === totalPages" aria-label="Next page" click.trigger="nextPage()">
45
+ <svg class="ui-table__pagination-icon" viewBox="0 0 24 24" aria-hidden="true">
46
+ <path d="M9 6l6 6-6 6" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path>
47
+ </svg>
48
+ </button>
49
+ <button ui-icon-button type="button" disabled.bind="page === totalPages" aria-label="Last page" click.trigger="lastPage()">
50
+ <svg class="ui-table__pagination-icon" viewBox="0 0 24 24" aria-hidden="true">
51
+ <path d="M18 5v14M6 6l6 6-6 6" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"></path>
52
+ </svg>
53
+ </button>
54
+ </div>
55
+ </div>
56
+ </template>