@dodlhuat/basix 1.1.1 → 1.2.1

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 (352) hide show
  1. package/README.md +706 -482
  2. package/css/accordion.scss +86 -87
  3. package/css/alert.scss +137 -137
  4. package/css/badge.scss +104 -0
  5. package/css/bottom-sheet.scss +192 -0
  6. package/css/breadcrumb.scss +158 -0
  7. package/css/button.scss +48 -0
  8. package/css/calendar.scss +957 -0
  9. package/css/card.scss +65 -65
  10. package/css/chart.scss +270 -157
  11. package/css/chat-bubbles.scss +134 -68
  12. package/css/chips.scss +109 -19
  13. package/css/colors.scss +32 -32
  14. package/css/context-menu.scss +182 -0
  15. package/css/datepicker.scss +336 -336
  16. package/css/defaults.scss +90 -90
  17. package/css/docs.scss +529 -0
  18. package/css/editor.scss +664 -461
  19. package/css/file-uploader.scss +1 -1
  20. package/css/flyout-menu.scss +361 -361
  21. package/css/form.scss +124 -0
  22. package/css/gallery.scss +65 -6
  23. package/css/grid.scss +41 -40
  24. package/css/group-picker.scss +345 -0
  25. package/css/guitar-chords.css +250 -250
  26. package/css/icons.scss +330 -330
  27. package/css/parameters.scss +3 -3
  28. package/css/placeholder.scss +33 -33
  29. package/css/popover.scss +206 -0
  30. package/css/progress.scss +76 -32
  31. package/css/properties.scss +51 -36
  32. package/css/push-menu.scss +302 -174
  33. package/css/reset.scss +39 -39
  34. package/css/scrollbar.scss +62 -5
  35. package/css/sidebar-nav.scss +92 -0
  36. package/css/spinner.scss +65 -65
  37. package/css/stepper.scss +248 -0
  38. package/css/style.css +4603 -273
  39. package/css/style.css.map +1 -1
  40. package/css/style.min.css +1 -1
  41. package/css/style.scss +51 -39
  42. package/css/table.scss +199 -199
  43. package/css/tabs.scss +154 -123
  44. package/css/timeline.scss +83 -38
  45. package/css/timepicker.scss +100 -5
  46. package/css/toast.scss +81 -81
  47. package/css/typography.scss +194 -161
  48. package/css/virtual-dropdown.scss +35 -29
  49. package/js/bottom-sheet.js +173 -0
  50. package/js/bottom-sheet.ts +222 -0
  51. package/js/calendar.js +532 -0
  52. package/js/calendar.ts +706 -0
  53. package/js/carousel.js +26 -13
  54. package/js/chart.js +573 -257
  55. package/js/chart.ts +692 -0
  56. package/js/code-viewer.js +10 -10
  57. package/js/code-viewer.ts +188 -188
  58. package/js/context-menu.js +212 -0
  59. package/js/context-menu.ts +252 -0
  60. package/js/datepicker.ts +627 -627
  61. package/js/docs-nav.js +204 -0
  62. package/js/dropdown.ts +179 -179
  63. package/js/editor.js +96 -38
  64. package/js/editor.ts +483 -425
  65. package/js/file-uploader.js +1 -0
  66. package/js/file-uploader.ts +1 -0
  67. package/js/flyout-menu.js +14 -14
  68. package/js/flyout-menu.ts +249 -249
  69. package/js/form-builder.js +106 -106
  70. package/js/gallery.js +13 -6
  71. package/js/gallery.ts +245 -236
  72. package/js/group-picker.js +342 -0
  73. package/js/group-picker.ts +447 -0
  74. package/js/guitar-chords.js +268 -268
  75. package/js/lazy-loader.js +121 -121
  76. package/js/modal.ts +166 -166
  77. package/js/popover.js +163 -0
  78. package/js/popover.ts +219 -0
  79. package/js/position.js +108 -0
  80. package/js/position.ts +111 -0
  81. package/js/push-menu.js +226 -113
  82. package/js/push-menu.ts +284 -145
  83. package/js/request.js +50 -50
  84. package/js/scroll.ts +47 -47
  85. package/js/scrollbar.js +13 -0
  86. package/js/scrollbar.ts +324 -307
  87. package/js/select.ts +216 -216
  88. package/js/sidebar-nav.js +41 -0
  89. package/js/sidebar-nav.ts +66 -0
  90. package/js/stepper.js +80 -0
  91. package/js/stepper.ts +104 -0
  92. package/js/table.ts +452 -452
  93. package/js/tabs.ts +279 -279
  94. package/js/theme.js +17 -6
  95. package/js/theme.ts +234 -224
  96. package/js/timepicker.js +21 -8
  97. package/js/toast.ts +137 -137
  98. package/js/tooltip.js +6 -60
  99. package/js/tooltip.ts +184 -251
  100. package/js/tsconfig.json +18 -18
  101. package/js/utils.ts +83 -83
  102. package/js/virtual-dropdown.js +25 -25
  103. package/js/virtual-dropdown.ts +365 -365
  104. package/package.json +39 -39
  105. package/fonts/Outfit-VariableFont_wght.woff +0 -0
  106. package/fonts/material-icons.woff2 +0 -0
  107. package/icons/activity-outline.svg +0 -1
  108. package/icons/alert-circle-outline.svg +0 -1
  109. package/icons/alert-triangle-outline.svg +0 -1
  110. package/icons/archive-outline.svg +0 -1
  111. package/icons/arrow-back-outline.svg +0 -1
  112. package/icons/arrow-circle-down-outline.svg +0 -1
  113. package/icons/arrow-circle-left-outline.svg +0 -1
  114. package/icons/arrow-circle-right-outline.svg +0 -1
  115. package/icons/arrow-circle-up-outline.svg +0 -1
  116. package/icons/arrow-down-outline.svg +0 -1
  117. package/icons/arrow-downward-outline.svg +0 -1
  118. package/icons/arrow-forward-outline.svg +0 -1
  119. package/icons/arrow-ios-back-outline.svg +0 -1
  120. package/icons/arrow-ios-downward-outline.svg +0 -1
  121. package/icons/arrow-ios-forward-outline.svg +0 -1
  122. package/icons/arrow-ios-upward-outline.svg +0 -1
  123. package/icons/arrow-left-outline.svg +0 -1
  124. package/icons/arrow-right-outline.svg +0 -1
  125. package/icons/arrow-up-outline.svg +0 -1
  126. package/icons/arrow-upward-outline.svg +0 -1
  127. package/icons/arrowhead-down-outline.svg +0 -1
  128. package/icons/arrowhead-left-outline.svg +0 -1
  129. package/icons/arrowhead-right-outline.svg +0 -1
  130. package/icons/arrowhead-up-outline.svg +0 -1
  131. package/icons/at-outline.svg +0 -1
  132. package/icons/attach-2-outline.svg +0 -1
  133. package/icons/attach-outline.svg +0 -1
  134. package/icons/award-outline.svg +0 -1
  135. package/icons/backspace-outline.svg +0 -1
  136. package/icons/bar-chart-2-outline.svg +0 -1
  137. package/icons/bar-chart-outline.svg +0 -1
  138. package/icons/battery-outline.svg +0 -1
  139. package/icons/behance-outline.svg +0 -1
  140. package/icons/bell-off-outline.svg +0 -1
  141. package/icons/bell-outline.svg +0 -1
  142. package/icons/bluetooth-outline.svg +0 -1
  143. package/icons/book-open-outline.svg +0 -1
  144. package/icons/book-outline.svg +0 -1
  145. package/icons/bookmark-outline.svg +0 -1
  146. package/icons/briefcase-outline.svg +0 -1
  147. package/icons/browser-outline.svg +0 -1
  148. package/icons/brush-outline.svg +0 -1
  149. package/icons/bulb-outline.svg +0 -1
  150. package/icons/calendar-outline.svg +0 -1
  151. package/icons/camera-outline.svg +0 -1
  152. package/icons/car-outline.svg +0 -1
  153. package/icons/cast-outline.svg +0 -1
  154. package/icons/charging-outline.svg +0 -1
  155. package/icons/checkmark-circle-2-outline.svg +0 -1
  156. package/icons/checkmark-circle-outline.svg +0 -1
  157. package/icons/checkmark-outline.svg +0 -1
  158. package/icons/checkmark-square-2-outline.svg +0 -1
  159. package/icons/checkmark-square-outline.svg +0 -1
  160. package/icons/chevron-down-outline.svg +0 -1
  161. package/icons/chevron-left-outline.svg +0 -1
  162. package/icons/chevron-right-outline.svg +0 -1
  163. package/icons/chevron-up-outline.svg +0 -1
  164. package/icons/clipboard-outline.svg +0 -1
  165. package/icons/clock-outline.svg +0 -1
  166. package/icons/close-circle-outline.svg +0 -1
  167. package/icons/close-outline.svg +0 -1
  168. package/icons/close-square-outline.svg +0 -1
  169. package/icons/cloud-download-outline.svg +0 -1
  170. package/icons/cloud-upload-outline.svg +0 -1
  171. package/icons/code-download-outline.svg +0 -1
  172. package/icons/code-outline.svg +0 -1
  173. package/icons/collapse-outline.svg +0 -1
  174. package/icons/color-palette-outline.svg +0 -1
  175. package/icons/color-picker-outline.svg +0 -1
  176. package/icons/compass-outline.svg +0 -1
  177. package/icons/copy-outline.svg +0 -1
  178. package/icons/corner-down-left-outline.svg +0 -1
  179. package/icons/corner-down-right-outline.svg +0 -1
  180. package/icons/corner-left-down-outline.svg +0 -1
  181. package/icons/corner-left-up-outline.svg +0 -1
  182. package/icons/corner-right-down-outline.svg +0 -1
  183. package/icons/corner-right-up-outline.svg +0 -1
  184. package/icons/corner-up-left-outline.svg +0 -1
  185. package/icons/corner-up-right-outline.svg +0 -1
  186. package/icons/credit-card-outline.svg +0 -1
  187. package/icons/crop-outline.svg +0 -1
  188. package/icons/cube-outline.svg +0 -1
  189. package/icons/diagonal-arrow-left-down-outline.svg +0 -1
  190. package/icons/diagonal-arrow-left-up-outline.svg +0 -1
  191. package/icons/diagonal-arrow-right-down-outline.svg +0 -1
  192. package/icons/diagonal-arrow-right-up-outline.svg +0 -1
  193. package/icons/done-all-outline.svg +0 -1
  194. package/icons/download-outline.svg +0 -1
  195. package/icons/droplet-off-outline.svg +0 -1
  196. package/icons/droplet-outline.svg +0 -1
  197. package/icons/edit-2-outline.svg +0 -1
  198. package/icons/edit-outline.svg +0 -1
  199. package/icons/email-outline.svg +0 -1
  200. package/icons/expand-outline.svg +0 -1
  201. package/icons/external-link-outline.svg +0 -1
  202. package/icons/eye-off-2-outline.svg +0 -1
  203. package/icons/eye-off-outline.svg +0 -1
  204. package/icons/eye-outline.svg +0 -1
  205. package/icons/facebook-outline.svg +0 -1
  206. package/icons/file-add-outline.svg +0 -1
  207. package/icons/file-outline.svg +0 -1
  208. package/icons/file-remove-outline.svg +0 -1
  209. package/icons/file-text-outline.svg +0 -1
  210. package/icons/film-outline.svg +0 -1
  211. package/icons/flag-outline.svg +0 -1
  212. package/icons/flash-off-outline.svg +0 -1
  213. package/icons/flash-outline.svg +0 -1
  214. package/icons/flip-2-outline.svg +0 -1
  215. package/icons/flip-outline.svg +0 -1
  216. package/icons/folder-add-outline.svg +0 -1
  217. package/icons/folder-outline.svg +0 -1
  218. package/icons/folder-remove-outline.svg +0 -1
  219. package/icons/funnel-outline.svg +0 -1
  220. package/icons/gift-outline.svg +0 -1
  221. package/icons/github-outline.svg +0 -1
  222. package/icons/globe-2-outline.svg +0 -1
  223. package/icons/globe-outline.svg +0 -1
  224. package/icons/google-outline.svg +0 -1
  225. package/icons/grid-outline.svg +0 -1
  226. package/icons/hard-drive-outline.svg +0 -1
  227. package/icons/hash-outline.svg +0 -1
  228. package/icons/headphones-outline.svg +0 -1
  229. package/icons/heart-outline.svg +0 -1
  230. package/icons/home-outline.svg +0 -1
  231. package/icons/image-outline.svg +0 -1
  232. package/icons/inbox-outline.svg +0 -1
  233. package/icons/info-outline.svg +0 -1
  234. package/icons/keypad-outline.svg +0 -1
  235. package/icons/layers-outline.svg +0 -1
  236. package/icons/layout-outline.svg +0 -1
  237. package/icons/link-2-outline.svg +0 -1
  238. package/icons/link-outline.svg +0 -1
  239. package/icons/linkedin-outline.svg +0 -1
  240. package/icons/list-outline.svg +0 -1
  241. package/icons/loader-outline.svg +0 -1
  242. package/icons/lock-outline.svg +0 -1
  243. package/icons/log-in-outline.svg +0 -1
  244. package/icons/log-out-outline.svg +0 -1
  245. package/icons/map-outline.svg +0 -1
  246. package/icons/maximize-outline.svg +0 -1
  247. package/icons/menu-2-outline.svg +0 -1
  248. package/icons/menu-arrow-outline.svg +0 -1
  249. package/icons/menu-outline.svg +0 -1
  250. package/icons/message-circle-outline.svg +0 -1
  251. package/icons/message-square-outline.svg +0 -1
  252. package/icons/mic-off-outline.svg +0 -1
  253. package/icons/mic-outline.svg +0 -1
  254. package/icons/minimize-outline.svg +0 -1
  255. package/icons/minus-circle-outline.svg +0 -1
  256. package/icons/minus-outline.svg +0 -1
  257. package/icons/minus-square-outline.svg +0 -1
  258. package/icons/monitor-outline.svg +0 -1
  259. package/icons/moon-outline.svg +0 -1
  260. package/icons/more-horizontal-outline.svg +0 -1
  261. package/icons/more-vertical-outline.svg +0 -1
  262. package/icons/move-outline.svg +0 -1
  263. package/icons/music-outline.svg +0 -1
  264. package/icons/navigation-2-outline.svg +0 -1
  265. package/icons/navigation-outline.svg +0 -1
  266. package/icons/npm-outline.svg +0 -1
  267. package/icons/options-2-outline.svg +0 -1
  268. package/icons/options-outline.svg +0 -1
  269. package/icons/pantone-outline.svg +0 -1
  270. package/icons/paper-plane-outline.svg +0 -1
  271. package/icons/pause-circle-outline.svg +0 -1
  272. package/icons/people-outline.svg +0 -1
  273. package/icons/percent-outline.svg +0 -1
  274. package/icons/person-add-outline.svg +0 -1
  275. package/icons/person-delete-outline.svg +0 -1
  276. package/icons/person-done-outline.svg +0 -1
  277. package/icons/person-outline.svg +0 -1
  278. package/icons/person-remove-outline.svg +0 -1
  279. package/icons/phone-call-outline.svg +0 -1
  280. package/icons/phone-missed-outline.svg +0 -1
  281. package/icons/phone-off-outline.svg +0 -1
  282. package/icons/phone-outline.svg +0 -1
  283. package/icons/pie-chart-outline.svg +0 -1
  284. package/icons/pin-outline.svg +0 -1
  285. package/icons/play-circle-outline.svg +0 -1
  286. package/icons/plus-circle-outline.svg +0 -1
  287. package/icons/plus-outline.svg +0 -1
  288. package/icons/plus-square-outline.svg +0 -1
  289. package/icons/power-outline.svg +0 -1
  290. package/icons/pricetags-outline.svg +0 -1
  291. package/icons/printer-outline.svg +0 -1
  292. package/icons/question-mark-circle-outline.svg +0 -1
  293. package/icons/question-mark-outline.svg +0 -1
  294. package/icons/radio-button-off-outline.svg +0 -1
  295. package/icons/radio-button-on-outline.svg +0 -1
  296. package/icons/radio-outline.svg +0 -1
  297. package/icons/recording-outline.svg +0 -1
  298. package/icons/refresh-outline.svg +0 -1
  299. package/icons/repeat-outline.svg +0 -1
  300. package/icons/rewind-left-outline.svg +0 -1
  301. package/icons/rewind-right-outline.svg +0 -1
  302. package/icons/save-outline.svg +0 -1
  303. package/icons/scissors-outline.svg +0 -1
  304. package/icons/search-outline.svg +0 -1
  305. package/icons/settings-2-outline.svg +0 -1
  306. package/icons/settings-outline.svg +0 -1
  307. package/icons/shake-outline.svg +0 -1
  308. package/icons/share-outline.svg +0 -1
  309. package/icons/shield-off-outline.svg +0 -1
  310. package/icons/shield-outline.svg +0 -1
  311. package/icons/shopping-bag-outline.svg +0 -1
  312. package/icons/shopping-cart-outline.svg +0 -1
  313. package/icons/shuffle-2-outline.svg +0 -1
  314. package/icons/shuffle-outline.svg +0 -1
  315. package/icons/skip-back-outline.svg +0 -1
  316. package/icons/skip-forward-outline.svg +0 -1
  317. package/icons/slash-outline.svg +0 -1
  318. package/icons/smartphone-outline.svg +0 -1
  319. package/icons/smiling-face-outline.svg +0 -1
  320. package/icons/speaker-outline.svg +0 -1
  321. package/icons/square-outline.svg +0 -1
  322. package/icons/star-outline.svg +0 -1
  323. package/icons/stop-circle-outline.svg +0 -1
  324. package/icons/sun-outline.svg +0 -1
  325. package/icons/swap-outline.svg +0 -1
  326. package/icons/sync-outline.svg +0 -1
  327. package/icons/text-outline.svg +0 -1
  328. package/icons/thermometer-minus-outline.svg +0 -1
  329. package/icons/thermometer-outline.svg +0 -1
  330. package/icons/thermometer-plus-outline.svg +0 -1
  331. package/icons/toggle-left-outline.svg +0 -1
  332. package/icons/toggle-right-outline.svg +0 -1
  333. package/icons/trash-2-outline.svg +0 -1
  334. package/icons/trash-outline.svg +0 -1
  335. package/icons/trending-down-outline.svg +0 -1
  336. package/icons/trending-up-outline.svg +0 -1
  337. package/icons/tv-outline.svg +0 -1
  338. package/icons/twitter-outline.svg +0 -1
  339. package/icons/umbrella-outline.svg +0 -1
  340. package/icons/undo-outline.svg +0 -1
  341. package/icons/unlock-outline.svg +0 -1
  342. package/icons/upload-outline.svg +0 -1
  343. package/icons/video-off-outline.svg +0 -1
  344. package/icons/video-outline.svg +0 -1
  345. package/icons/volume-down-outline.svg +0 -1
  346. package/icons/volume-mute-outline.svg +0 -1
  347. package/icons/volume-off-outline.svg +0 -1
  348. package/icons/volume-up-outline.svg +0 -1
  349. package/icons/wifi-off-outline.svg +0 -1
  350. package/icons/wifi-outline.svg +0 -1
  351. package/js/index.js +0 -718
  352. package/js/index.ts +0 -873
package/js/push-menu.ts CHANGED
@@ -1,145 +1,284 @@
1
- interface PushMenuElements {
2
- navigation: HTMLElement | null;
3
- content: HTMLElement | null;
4
- menu: HTMLElement | null;
5
- header: HTMLElement | null;
6
- controlIcon: HTMLElement | null;
7
- backdrop: HTMLElement | null;
8
- }
9
-
10
- class PushMenu {
11
- private static elements: PushMenuElements = {
12
- navigation: null,
13
- content: null,
14
- menu: null,
15
- header: null,
16
- controlIcon: null,
17
- backdrop: null
18
- };
19
-
20
- private static initialized = false;
21
-
22
- public static init(): void {
23
- if (this.initialized) {
24
- console.warn('PushMenu: Already initialized');
25
- return;
26
- }
27
-
28
- this.refresh();
29
-
30
- if (!this.elements.navigation || !this.elements.content) {
31
- throw new Error('PushMenu: Required elements not found (.navigation, .push-content)');
32
- }
33
-
34
- this.elements.navigation.addEventListener('change', this.handleNavigationChange.bind(this));
35
-
36
- this.elements.backdrop?.addEventListener('click', this.handleBackdropClick);
37
-
38
- this.initialized = true;
39
- }
40
-
41
- private static handleNavigationChange(): void {
42
- const isPushed = this.elements.content?.classList.contains('pushed') ?? false;
43
-
44
- if (!isPushed) {
45
- this.elements.content?.addEventListener('click', this.clickNav);
46
- } else {
47
- this.elements.content?.removeEventListener('click', this.clickNav);
48
- }
49
-
50
- this.pushToggle();
51
- }
52
-
53
- public static pushToggle(): void {
54
- if (!this.elements.content || !this.elements.menu) {
55
- throw new Error('PushMenu: Required elements not found (.push-content, .push-menu)');
56
- }
57
-
58
- const isPushed = this.elements.content.classList.contains('pushed');
59
-
60
- this.toggleClass(this.elements.content, 'pushed', !isPushed);
61
- this.toggleClass(this.elements.menu, 'pushed', !isPushed);
62
- this.toggleClass(this.elements.header, 'pushed', !isPushed);
63
- this.toggleClass(this.elements.backdrop, 'pushed', !isPushed);
64
-
65
- if (this.elements.controlIcon) {
66
- if (isPushed) {
67
- this.elements.controlIcon.classList.remove('icon-menu_open');
68
- this.elements.controlIcon.classList.add('icon-menu');
69
- } else {
70
- this.elements.controlIcon.classList.add('icon-menu_open');
71
- this.elements.controlIcon.classList.remove('icon-menu');
72
- }
73
- }
74
- }
75
-
76
- private static toggleClass(element: HTMLElement | null, className: string, add: boolean): void {
77
- if (!element) return;
78
-
79
- if (add) {
80
- element.classList.add(className);
81
- } else {
82
- element.classList.remove(className);
83
- }
84
- }
85
-
86
- private static clickNav = (): void => {
87
- const navigation = PushMenu.elements.navigation as HTMLElement;
88
- navigation?.click();
89
- };
90
-
91
- private static handleBackdropClick = (): void => {
92
- if (PushMenu.isOpen()) {
93
- const navigation = PushMenu.elements.navigation as HTMLElement;
94
- navigation?.click();
95
- }
96
- };
97
-
98
- public static open(): void {
99
- if (!this.elements.content?.classList.contains('pushed')) {
100
- this.pushToggle();
101
- }
102
- }
103
-
104
- public static close(): void {
105
- if (this.elements.content?.classList.contains('pushed')) {
106
- this.pushToggle();
107
- }
108
- }
109
-
110
- public static isOpen(): boolean {
111
- return this.elements.content?.classList.contains('pushed') ?? false;
112
- }
113
-
114
- public static destroy(): void {
115
- if (!this.initialized) return;
116
-
117
- this.elements.navigation?.removeEventListener('change', this.handleNavigationChange);
118
- this.elements.content?.removeEventListener('click', this.clickNav);
119
- this.elements.backdrop?.removeEventListener('click', this.handleBackdropClick);
120
-
121
- this.close();
122
-
123
- this.elements = {
124
- navigation: null,
125
- content: null,
126
- menu: null,
127
- header: null,
128
- controlIcon: null,
129
- backdrop: null
130
- };
131
-
132
- this.initialized = false;
133
- }
134
-
135
- public static refresh(): void {
136
- this.elements.navigation = document.querySelector('.navigation');
137
- this.elements.content = document.querySelector('.push-content');
138
- this.elements.menu = document.querySelector('.push-menu');
139
- this.elements.header = document.querySelector('.main-header');
140
- this.elements.controlIcon = document.querySelector('.navigation-controls .icon');
141
- this.elements.backdrop = document.querySelector('.push-menu-backdrop');
142
- }
143
- }
144
-
145
- export { PushMenu, type PushMenuElements };
1
+ interface PushMenuElements {
2
+ navigation: HTMLElement | null;
3
+ content: HTMLElement | null;
4
+ menu: HTMLElement | null;
5
+ header: HTMLElement | null;
6
+ controlIcon: HTMLElement | null;
7
+ backdrop: HTMLElement | null;
8
+ }
9
+
10
+ class PushMenu {
11
+ private static elements: PushMenuElements = {
12
+ navigation: null,
13
+ content: null,
14
+ menu: null,
15
+ header: null,
16
+ controlIcon: null,
17
+ backdrop: null
18
+ };
19
+
20
+ private static initialized = false;
21
+ private static panelStack: HTMLElement[] = [];
22
+
23
+ public static init(): void {
24
+ if (this.initialized) {
25
+ console.warn('PushMenu: Already initialized');
26
+ return;
27
+ }
28
+
29
+ this.refresh();
30
+
31
+ if (!this.elements.navigation || !this.elements.content) {
32
+ throw new Error('PushMenu: Required elements not found (.navigation, .push-content)');
33
+ }
34
+
35
+ this.buildPanels();
36
+
37
+ this.elements.navigation.addEventListener('change', this.handleNavigationChange.bind(this));
38
+ this.elements.backdrop?.addEventListener('click', this.handleBackdropClick);
39
+
40
+ this.initialized = true;
41
+ }
42
+
43
+ // ─── Panel construction ────────────────────────────────────────────────
44
+
45
+ private static buildPanels(): void {
46
+ const menu = this.elements.menu;
47
+ if (!menu) return;
48
+
49
+ const rootUl = menu.querySelector(':scope > ul');
50
+ if (!rootUl) return;
51
+
52
+ // Wrap root ul in a panel
53
+ const rootPanel = document.createElement('div');
54
+ rootPanel.classList.add('push-menu-panel', 'is-active');
55
+ rootPanel.dataset.level = '0';
56
+ rootPanel.appendChild(rootUl);
57
+ menu.appendChild(rootPanel);
58
+
59
+ // Recursively extract nested uls into sibling panels
60
+ this.extractSubPanels(rootPanel, 1);
61
+
62
+ this.panelStack = [rootPanel];
63
+ }
64
+
65
+ private static extractSubPanels(panel: HTMLElement, level: number): void {
66
+ // Collect all uls currently in this panel before any mutations
67
+ const uls = Array.from(panel.querySelectorAll('ul')) as HTMLUListElement[];
68
+
69
+ for (const ul of uls) {
70
+ const listItems = Array.from(ul.children) as HTMLElement[];
71
+
72
+ for (const li of listItems) {
73
+ const childUl = li.querySelector(':scope > ul') as HTMLElement | null;
74
+ if (!childUl) continue;
75
+
76
+ // Determine label from the immediate anchor child
77
+ const parentAnchor = li.querySelector(':scope > a') as HTMLElement | null;
78
+ const title = parentAnchor?.textContent?.trim() ?? '';
79
+
80
+ // ── Build sub-panel ──────────────────────────────────────
81
+ const subPanel = document.createElement('div');
82
+ subPanel.classList.add('push-menu-panel');
83
+ subPanel.dataset.level = String(level);
84
+
85
+ // Header: back button + breadcrumb title
86
+ const header = document.createElement('div');
87
+ header.classList.add('push-menu-panel-header');
88
+
89
+ const backBtn = document.createElement('button');
90
+ backBtn.classList.add('push-menu-back');
91
+ backBtn.setAttribute('aria-label', 'Back');
92
+ backBtn.innerHTML = `<span class="icon icon-navigate_before" aria-hidden="true"></span>`;
93
+ header.addEventListener('click', () => PushMenu.goBack());
94
+
95
+ const titleEl = document.createElement('span');
96
+ titleEl.classList.add('push-menu-panel-title');
97
+ titleEl.textContent = title;
98
+
99
+ header.appendChild(backBtn);
100
+ header.appendChild(titleEl);
101
+ subPanel.appendChild(header);
102
+
103
+ // Move the child ul into the sub-panel
104
+ subPanel.appendChild(childUl);
105
+
106
+ // Append sub-panel as sibling inside the nav
107
+ this.elements.menu?.appendChild(subPanel);
108
+
109
+ // ── Replace anchor with a trigger span in the parent li ──
110
+ const trigger = document.createElement('span');
111
+ trigger.classList.add('push-menu-item');
112
+ trigger.textContent = title;
113
+
114
+ // Chevron icon
115
+ const chevron = document.createElement('span');
116
+ chevron.classList.add('push-menu-chevron');
117
+ chevron.setAttribute('aria-hidden', 'true');
118
+ chevron.innerHTML = `<span class="icon icon-navigate_next" aria-hidden="true"></span>`;
119
+ trigger.appendChild(chevron);
120
+
121
+ if (parentAnchor) {
122
+ parentAnchor.replaceWith(trigger);
123
+ } else {
124
+ li.prepend(trigger);
125
+ }
126
+
127
+ trigger.addEventListener('click', () => PushMenu.openPanel(subPanel));
128
+
129
+ // Recurse into the newly created sub-panel
130
+ this.extractSubPanels(subPanel, level + 1);
131
+ }
132
+ }
133
+ }
134
+
135
+ // ─── Panel navigation ──────────────────────────────────────────────────
136
+
137
+ public static openPanel(panel: HTMLElement): void {
138
+ const currentPanel = this.panelStack[this.panelStack.length - 1];
139
+
140
+ currentPanel.classList.remove('is-active');
141
+ currentPanel.classList.add('is-prev');
142
+
143
+ panel.classList.add('is-active');
144
+
145
+ this.panelStack.push(panel);
146
+ }
147
+
148
+ public static goBack(): void {
149
+ if (this.panelStack.length <= 1) return;
150
+
151
+ const currentPanel = this.panelStack.pop()!;
152
+ const prevPanel = this.panelStack[this.panelStack.length - 1];
153
+
154
+ currentPanel.classList.remove('is-active');
155
+ prevPanel.classList.remove('is-prev');
156
+ prevPanel.classList.add('is-active');
157
+ }
158
+
159
+ private static resetPanels(): void {
160
+ const menu = this.elements.menu;
161
+ if (!menu) return;
162
+
163
+ // Wait for the close animation before snapping panels back
164
+ setTimeout(() => {
165
+ const panels = Array.from(menu.querySelectorAll('.push-menu-panel')) as HTMLElement[];
166
+ panels.forEach((panel, index) => {
167
+ panel.classList.remove('is-active', 'is-prev');
168
+ if (index === 0) panel.classList.add('is-active');
169
+ });
170
+
171
+ if (panels[0]) {
172
+ this.panelStack = [panels[0]];
173
+ }
174
+ }, 300);
175
+ }
176
+
177
+ // ─── Open / close ──────────────────────────────────────────────────────
178
+
179
+ private static handleNavigationChange(): void {
180
+ const isPushed = this.elements.content?.classList.contains('pushed') ?? false;
181
+
182
+ if (!isPushed) {
183
+ this.elements.content?.addEventListener('click', this.clickNav);
184
+ } else {
185
+ this.elements.content?.removeEventListener('click', this.clickNav);
186
+ this.resetPanels();
187
+ }
188
+
189
+ this.pushToggle();
190
+ }
191
+
192
+ public static pushToggle(): void {
193
+ if (!this.elements.content || !this.elements.menu) {
194
+ throw new Error('PushMenu: Required elements not found (.push-content, .push-menu)');
195
+ }
196
+
197
+ const isPushed = this.elements.content.classList.contains('pushed');
198
+
199
+ this.toggleClass(this.elements.content, 'pushed', !isPushed);
200
+ this.toggleClass(this.elements.menu, 'pushed', !isPushed);
201
+ this.toggleClass(this.elements.header, 'pushed', !isPushed);
202
+ this.toggleClass(this.elements.backdrop, 'pushed', !isPushed);
203
+
204
+ if (this.elements.controlIcon) {
205
+ if (isPushed) {
206
+ this.elements.controlIcon.classList.remove('icon-menu_open');
207
+ this.elements.controlIcon.classList.add('icon-menu');
208
+ } else {
209
+ this.elements.controlIcon.classList.add('icon-menu_open');
210
+ this.elements.controlIcon.classList.remove('icon-menu');
211
+ }
212
+ }
213
+ }
214
+
215
+ private static toggleClass(element: HTMLElement | null, className: string, add: boolean): void {
216
+ if (!element) return;
217
+ if (add) {
218
+ element.classList.add(className);
219
+ } else {
220
+ element.classList.remove(className);
221
+ }
222
+ }
223
+
224
+ private static clickNav = (): void => {
225
+ const navigation = PushMenu.elements.navigation as HTMLElement;
226
+ navigation?.click();
227
+ };
228
+
229
+ private static handleBackdropClick = (): void => {
230
+ if (PushMenu.isOpen()) {
231
+ const navigation = PushMenu.elements.navigation as HTMLElement;
232
+ navigation?.click();
233
+ }
234
+ };
235
+
236
+ public static open(): void {
237
+ if (!this.elements.content?.classList.contains('pushed')) {
238
+ this.pushToggle();
239
+ }
240
+ }
241
+
242
+ public static close(): void {
243
+ if (this.elements.content?.classList.contains('pushed')) {
244
+ this.pushToggle();
245
+ }
246
+ }
247
+
248
+ public static isOpen(): boolean {
249
+ return this.elements.content?.classList.contains('pushed') ?? false;
250
+ }
251
+
252
+ public static destroy(): void {
253
+ if (!this.initialized) return;
254
+
255
+ this.elements.navigation?.removeEventListener('change', this.handleNavigationChange);
256
+ this.elements.content?.removeEventListener('click', this.clickNav);
257
+ this.elements.backdrop?.removeEventListener('click', this.handleBackdropClick);
258
+
259
+ this.close();
260
+
261
+ this.elements = {
262
+ navigation: null,
263
+ content: null,
264
+ menu: null,
265
+ header: null,
266
+ controlIcon: null,
267
+ backdrop: null
268
+ };
269
+
270
+ this.panelStack = [];
271
+ this.initialized = false;
272
+ }
273
+
274
+ public static refresh(): void {
275
+ this.elements.navigation = document.querySelector('.navigation');
276
+ this.elements.content = document.querySelector('.push-content');
277
+ this.elements.menu = document.querySelector('.push-menu');
278
+ this.elements.header = document.querySelector('.main-header');
279
+ this.elements.controlIcon = document.querySelector('.navigation-controls .icon');
280
+ this.elements.backdrop = document.querySelector('.push-menu-backdrop');
281
+ }
282
+ }
283
+
284
+ export { PushMenu, type PushMenuElements };
package/js/request.js CHANGED
@@ -1,51 +1,51 @@
1
- class Request {
2
- constructor(url, parameters, success, error) {
3
- this.url = url;
4
- this.parameters = parameters;
5
- this.success = success;
6
- this.error = error;
7
- }
8
-
9
- get() {
10
- const checked = this.#checkSuccessError(this.success, this.error);
11
- if (this.parameters.data !== undefined) {
12
- this.url += '?' + new URLSearchParams(this.parameters.data);
13
- }
14
- fetch(this.url)
15
- .then(function(response) {
16
- return response.json();
17
- })
18
- .then(checked.success)
19
- .catch(checked.error);
20
- }
21
- post() {
22
- const checked = this.#checkSuccessError(this.success, this.error);
23
- fetch(this.url,
24
- {
25
- method: 'post',
26
- headers: {
27
- 'Accept': 'application/json',
28
- 'Content-Type': 'application/json'
29
- },
30
- body: JSON.stringify(this.parameters.data)
31
- })
32
- .then(checked.success)
33
- .catch(checked.error);
34
- }
35
-
36
- #checkSuccessError(success, error) {
37
- if (success === undefined) {
38
- success = function(data) {
39
- console.log(data);
40
- };
41
- }
42
- if (error === undefined) {
43
- error = function(error) {
44
- console.error(error);
45
- }
46
- }
47
- return {success, error};
48
- }
49
- }
50
-
1
+ class Request {
2
+ constructor(url, parameters, success, error) {
3
+ this.url = url;
4
+ this.parameters = parameters;
5
+ this.success = success;
6
+ this.error = error;
7
+ }
8
+
9
+ get() {
10
+ const checked = this.#checkSuccessError(this.success, this.error);
11
+ if (this.parameters.data !== undefined) {
12
+ this.url += '?' + new URLSearchParams(this.parameters.data);
13
+ }
14
+ fetch(this.url)
15
+ .then(function(response) {
16
+ return response.json();
17
+ })
18
+ .then(checked.success)
19
+ .catch(checked.error);
20
+ }
21
+ post() {
22
+ const checked = this.#checkSuccessError(this.success, this.error);
23
+ fetch(this.url,
24
+ {
25
+ method: 'post',
26
+ headers: {
27
+ 'Accept': 'application/json',
28
+ 'Content-Type': 'application/json'
29
+ },
30
+ body: JSON.stringify(this.parameters.data)
31
+ })
32
+ .then(checked.success)
33
+ .catch(checked.error);
34
+ }
35
+
36
+ #checkSuccessError(success, error) {
37
+ if (success === undefined) {
38
+ success = function(data) {
39
+ console.log(data);
40
+ };
41
+ }
42
+ if (error === undefined) {
43
+ error = function(error) {
44
+ console.error(error);
45
+ }
46
+ }
47
+ return {success, error};
48
+ }
49
+ }
50
+
51
51
  export {Request}
package/js/scroll.ts CHANGED
@@ -1,47 +1,47 @@
1
- interface ScrollOptions {
2
- behavior?: ScrollBehavior;
3
- offset?: number;
4
- block?: ScrollLogicalPosition;
5
- }
6
-
7
- class Scroll {
8
- public static to(target: string | Element, options: ScrollOptions = {}): void {
9
- const fixed_header = document.querySelector('.main-header') as HTMLElement | null;
10
- const offset = fixed_header ? fixed_header.offsetHeight : 0;
11
-
12
- const settings: Required<ScrollOptions> = {
13
- behavior: "smooth",
14
- offset: offset,
15
- block: "start",
16
- ...options
17
- };
18
-
19
- let el: Element | null = target instanceof Element ? target : null;
20
-
21
- if (typeof target === "string") {
22
- el = document.querySelector(target);
23
- }
24
-
25
- if (!el) return;
26
-
27
- const rect = el.getBoundingClientRect();
28
- const scrollTop = window.scrollY;
29
- const offsetTop = rect.top + scrollTop - settings.offset;
30
-
31
- window.scrollTo({
32
- top: offsetTop,
33
- behavior: settings.behavior
34
- });
35
- }
36
- }
37
-
38
- declare global {
39
- interface Window {
40
- Scroll: typeof Scroll;
41
- }
42
- }
43
-
44
- window.Scroll = Scroll;
45
-
46
- export { Scroll };
47
- export type { ScrollOptions };
1
+ interface ScrollOptions {
2
+ behavior?: ScrollBehavior;
3
+ offset?: number;
4
+ block?: ScrollLogicalPosition;
5
+ }
6
+
7
+ class Scroll {
8
+ public static to(target: string | Element, options: ScrollOptions = {}): void {
9
+ const fixed_header = document.querySelector('.main-header') as HTMLElement | null;
10
+ const offset = fixed_header ? fixed_header.offsetHeight : 0;
11
+
12
+ const settings: Required<ScrollOptions> = {
13
+ behavior: "smooth",
14
+ offset: offset,
15
+ block: "start",
16
+ ...options
17
+ };
18
+
19
+ let el: Element | null = target instanceof Element ? target : null;
20
+
21
+ if (typeof target === "string") {
22
+ el = document.querySelector(target);
23
+ }
24
+
25
+ if (!el) return;
26
+
27
+ const rect = el.getBoundingClientRect();
28
+ const scrollTop = window.scrollY;
29
+ const offsetTop = rect.top + scrollTop - settings.offset;
30
+
31
+ window.scrollTo({
32
+ top: offsetTop,
33
+ behavior: settings.behavior
34
+ });
35
+ }
36
+ }
37
+
38
+ declare global {
39
+ interface Window {
40
+ Scroll: typeof Scroll;
41
+ }
42
+ }
43
+
44
+ window.Scroll = Scroll;
45
+
46
+ export { Scroll };
47
+ export type { ScrollOptions };
package/js/scrollbar.js CHANGED
@@ -31,6 +31,7 @@ class Scrollbar {
31
31
  this.boundTrackClick = this.handleTrackClick.bind(this);
32
32
  this.boundViewportScroll = this.updateThumb.bind(this);
33
33
  this.boundUpdateThumb = this.updateThumb.bind(this);
34
+ this.boundContainerWheel = this.handleContainerWheel.bind(this);
34
35
  // Setup ResizeObserver
35
36
  this.ro = new ResizeObserver(this.boundUpdateThumb);
36
37
  // Initialize
@@ -80,6 +81,7 @@ class Scrollbar {
80
81
  this.viewport.addEventListener('scroll', this.boundViewportScroll, { passive: true });
81
82
  this.thumb.addEventListener('pointerdown', this.boundThumbPointerDown);
82
83
  this.track.addEventListener('click', this.boundTrackClick);
84
+ this.container.addEventListener('wheel', this.boundContainerWheel, { passive: false });
83
85
  // Observe size changes
84
86
  this.ro.observe(this.viewport);
85
87
  this.ro.observe(this.content);
@@ -182,11 +184,22 @@ class Scrollbar {
182
184
  const scrollTop = scrollRatio * (maxScroll || 0);
183
185
  this.viewport.scrollTo({ top: scrollTop, behavior: 'smooth' });
184
186
  }
187
+ handleContainerWheel(e) {
188
+ const { scrollTop, scrollHeight, clientHeight } = this.viewport;
189
+ const scrollable = scrollHeight > clientHeight;
190
+ const atTop = scrollTop === 0 && e.deltaY < 0;
191
+ const atBottom = scrollTop + clientHeight >= scrollHeight - 1 && e.deltaY > 0;
192
+ if (scrollable && !atTop && !atBottom) {
193
+ e.preventDefault();
194
+ }
195
+ this.viewport.scrollTop += e.deltaY;
196
+ }
185
197
  destroy() {
186
198
  // Remove event listeners
187
199
  this.viewport.removeEventListener('scroll', this.boundViewportScroll);
188
200
  this.thumb.removeEventListener('pointerdown', this.boundThumbPointerDown);
189
201
  this.track.removeEventListener('click', this.boundTrackClick);
202
+ this.container.removeEventListener('wheel', this.boundContainerWheel);
190
203
  window.removeEventListener('resize', this.boundUpdateThumb);
191
204
  // Disconnect observer
192
205
  this.ro.disconnect();