@dodlhuat/basix 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 (430) hide show
  1. package/README.md +482 -0
  2. package/css/accordion.css +109 -0
  3. package/css/accordion.css.map +1 -0
  4. package/css/accordion.scss +78 -0
  5. package/css/alert.css +57 -0
  6. package/css/alert.css.map +1 -0
  7. package/css/alert.scss +86 -0
  8. package/css/button.css +69 -0
  9. package/css/button.css.map +1 -0
  10. package/css/button.scss +102 -0
  11. package/css/card.css +144 -0
  12. package/css/card.css.map +1 -0
  13. package/css/card.scss +66 -0
  14. package/css/carousel.css +118 -0
  15. package/css/carousel.css.map +1 -0
  16. package/css/carousel.scss +87 -0
  17. package/css/chart.css +159 -0
  18. package/css/chart.css.map +1 -0
  19. package/css/chart.scss +159 -0
  20. package/css/chat-bubbles.css +97 -0
  21. package/css/chat-bubbles.css.map +1 -0
  22. package/css/chat-bubbles.scss +68 -0
  23. package/css/checkbox.css +77 -0
  24. package/css/checkbox.css.map +1 -0
  25. package/css/checkbox.scss +55 -0
  26. package/css/chips.css +72 -0
  27. package/css/chips.css.map +1 -0
  28. package/css/chips.scss +52 -0
  29. package/css/code-viewer.css +97 -0
  30. package/css/code-viewer.css.map +1 -0
  31. package/css/code-viewer.scss +98 -0
  32. package/css/colors.css +63 -0
  33. package/css/colors.css.map +1 -0
  34. package/css/colors.scss +33 -0
  35. package/css/datepicker.css +264 -0
  36. package/css/datepicker.css.map +1 -0
  37. package/css/datepicker.scss +317 -0
  38. package/css/defaults.css +118 -0
  39. package/css/defaults.css.map +1 -0
  40. package/css/defaults.scss +91 -0
  41. package/css/dropdown.css +146 -0
  42. package/css/dropdown.css.map +1 -0
  43. package/css/dropdown.scss +137 -0
  44. package/css/editor.css +413 -0
  45. package/css/editor.scss +458 -0
  46. package/css/file-uploader.css +194 -0
  47. package/css/file-uploader.css.map +1 -0
  48. package/css/file-uploader.scss +195 -0
  49. package/css/flyout-menu.css +345 -0
  50. package/css/flyout-menu.css.map +1 -0
  51. package/css/flyout-menu.scss +355 -0
  52. package/css/form-builder.css +9 -0
  53. package/css/form-builder.css.map +1 -0
  54. package/css/form-builder.scss +11 -0
  55. package/css/form.css +130 -0
  56. package/css/form.css.map +1 -0
  57. package/css/form.scss +115 -0
  58. package/css/gallery.css +91 -0
  59. package/css/gallery.css.map +1 -0
  60. package/css/gallery.scss +63 -0
  61. package/css/grid.css +44 -0
  62. package/css/grid.css.map +1 -0
  63. package/css/grid.scss +41 -0
  64. package/css/guitar-chords.css +251 -0
  65. package/css/icons.css +327 -0
  66. package/css/icons.css.map +1 -0
  67. package/css/icons.scss +331 -0
  68. package/css/modal.css +97 -0
  69. package/css/modal.css.map +1 -0
  70. package/css/modal.scss +72 -0
  71. package/css/parameters.css +1 -0
  72. package/css/parameters.css.map +1 -0
  73. package/css/parameters.scss +4 -0
  74. package/css/placeholder.css +50 -0
  75. package/css/placeholder.css.map +1 -0
  76. package/css/placeholder.scss +28 -0
  77. package/css/progress.css +51 -0
  78. package/css/progress.css.map +1 -0
  79. package/css/progress.scss +32 -0
  80. package/css/properties.css +31 -0
  81. package/css/properties.css.map +1 -0
  82. package/css/properties.scss +31 -0
  83. package/css/push-menu.css +145 -0
  84. package/css/push-menu.css.map +1 -0
  85. package/css/push-menu.scss +127 -0
  86. package/css/radiobutton.css +91 -0
  87. package/css/radiobutton.css.map +1 -0
  88. package/css/radiobutton.scss +64 -0
  89. package/css/reset.css +46 -0
  90. package/css/reset.css.map +1 -0
  91. package/css/reset.scss +40 -0
  92. package/css/scrollbar.css +91 -0
  93. package/css/scrollbar.css.map +1 -0
  94. package/css/scrollbar.scss +69 -0
  95. package/css/spinner.css +118 -0
  96. package/css/spinner.css.map +1 -0
  97. package/css/spinner.scss +91 -0
  98. package/css/style.css +3735 -0
  99. package/css/style.css.map +1 -0
  100. package/css/style.min.css +1 -0
  101. package/css/style.scss +38 -0
  102. package/css/switch.css +66 -0
  103. package/css/switch.css.map +1 -0
  104. package/css/switch.scss +42 -0
  105. package/css/table.css +201 -0
  106. package/css/table.css.map +1 -0
  107. package/css/table.scss +178 -0
  108. package/css/tabs.css +135 -0
  109. package/css/tabs.css.map +1 -0
  110. package/css/tabs.scss +118 -0
  111. package/css/timeline.css +69 -0
  112. package/css/timeline.css.map +1 -0
  113. package/css/timeline.scss +69 -0
  114. package/css/timepicker.scss +72 -0
  115. package/css/toast.css +98 -0
  116. package/css/toast.css.map +1 -0
  117. package/css/toast.scss +81 -0
  118. package/css/tooltip.css +151 -0
  119. package/css/tooltip.css.map +1 -0
  120. package/css/tooltip.scss +122 -0
  121. package/css/tree.css +199 -0
  122. package/css/tree.css.map +1 -0
  123. package/css/tree.scss +192 -0
  124. package/css/typography.css +137 -0
  125. package/css/typography.css.map +1 -0
  126. package/css/typography.scss +100 -0
  127. package/css/virtual-dropdown.css +149 -0
  128. package/css/virtual-dropdown.css.map +1 -0
  129. package/css/virtual-dropdown.scss +142 -0
  130. package/fonts/MaterialSymbolsOutlined.woff2 +0 -0
  131. package/fonts/Outfit-VariableFont_wght.woff +0 -0
  132. package/fonts/Outfit-VariableFont_wght.woff2 +0 -0
  133. package/fonts/material-icons.woff2 +0 -0
  134. package/icons/activity-outline.svg +1 -0
  135. package/icons/alert-circle-outline.svg +1 -0
  136. package/icons/alert-triangle-outline.svg +1 -0
  137. package/icons/archive-outline.svg +1 -0
  138. package/icons/arrow-back-outline.svg +1 -0
  139. package/icons/arrow-circle-down-outline.svg +1 -0
  140. package/icons/arrow-circle-left-outline.svg +1 -0
  141. package/icons/arrow-circle-right-outline.svg +1 -0
  142. package/icons/arrow-circle-up-outline.svg +1 -0
  143. package/icons/arrow-down-outline.svg +1 -0
  144. package/icons/arrow-downward-outline.svg +1 -0
  145. package/icons/arrow-forward-outline.svg +1 -0
  146. package/icons/arrow-ios-back-outline.svg +1 -0
  147. package/icons/arrow-ios-downward-outline.svg +1 -0
  148. package/icons/arrow-ios-forward-outline.svg +1 -0
  149. package/icons/arrow-ios-upward-outline.svg +1 -0
  150. package/icons/arrow-left-outline.svg +1 -0
  151. package/icons/arrow-right-outline.svg +1 -0
  152. package/icons/arrow-up-outline.svg +1 -0
  153. package/icons/arrow-upward-outline.svg +1 -0
  154. package/icons/arrowhead-down-outline.svg +1 -0
  155. package/icons/arrowhead-left-outline.svg +1 -0
  156. package/icons/arrowhead-right-outline.svg +1 -0
  157. package/icons/arrowhead-up-outline.svg +1 -0
  158. package/icons/at-outline.svg +1 -0
  159. package/icons/attach-2-outline.svg +1 -0
  160. package/icons/attach-outline.svg +1 -0
  161. package/icons/award-outline.svg +1 -0
  162. package/icons/backspace-outline.svg +1 -0
  163. package/icons/bar-chart-2-outline.svg +1 -0
  164. package/icons/bar-chart-outline.svg +1 -0
  165. package/icons/battery-outline.svg +1 -0
  166. package/icons/behance-outline.svg +1 -0
  167. package/icons/bell-off-outline.svg +1 -0
  168. package/icons/bell-outline.svg +1 -0
  169. package/icons/bluetooth-outline.svg +1 -0
  170. package/icons/book-open-outline.svg +1 -0
  171. package/icons/book-outline.svg +1 -0
  172. package/icons/bookmark-outline.svg +1 -0
  173. package/icons/briefcase-outline.svg +1 -0
  174. package/icons/browser-outline.svg +1 -0
  175. package/icons/brush-outline.svg +1 -0
  176. package/icons/bulb-outline.svg +1 -0
  177. package/icons/calendar-outline.svg +1 -0
  178. package/icons/camera-outline.svg +1 -0
  179. package/icons/car-outline.svg +1 -0
  180. package/icons/cast-outline.svg +1 -0
  181. package/icons/charging-outline.svg +1 -0
  182. package/icons/checkmark-circle-2-outline.svg +1 -0
  183. package/icons/checkmark-circle-outline.svg +1 -0
  184. package/icons/checkmark-outline.svg +1 -0
  185. package/icons/checkmark-square-2-outline.svg +1 -0
  186. package/icons/checkmark-square-outline.svg +1 -0
  187. package/icons/chevron-down-outline.svg +1 -0
  188. package/icons/chevron-left-outline.svg +1 -0
  189. package/icons/chevron-right-outline.svg +1 -0
  190. package/icons/chevron-up-outline.svg +1 -0
  191. package/icons/clipboard-outline.svg +1 -0
  192. package/icons/clock-outline.svg +1 -0
  193. package/icons/close-circle-outline.svg +1 -0
  194. package/icons/close-outline.svg +1 -0
  195. package/icons/close-square-outline.svg +1 -0
  196. package/icons/cloud-download-outline.svg +1 -0
  197. package/icons/cloud-upload-outline.svg +1 -0
  198. package/icons/code-download-outline.svg +1 -0
  199. package/icons/code-outline.svg +1 -0
  200. package/icons/collapse-outline.svg +1 -0
  201. package/icons/color-palette-outline.svg +1 -0
  202. package/icons/color-picker-outline.svg +1 -0
  203. package/icons/compass-outline.svg +1 -0
  204. package/icons/copy-outline.svg +1 -0
  205. package/icons/corner-down-left-outline.svg +1 -0
  206. package/icons/corner-down-right-outline.svg +1 -0
  207. package/icons/corner-left-down-outline.svg +1 -0
  208. package/icons/corner-left-up-outline.svg +1 -0
  209. package/icons/corner-right-down-outline.svg +1 -0
  210. package/icons/corner-right-up-outline.svg +1 -0
  211. package/icons/corner-up-left-outline.svg +1 -0
  212. package/icons/corner-up-right-outline.svg +1 -0
  213. package/icons/credit-card-outline.svg +1 -0
  214. package/icons/crop-outline.svg +1 -0
  215. package/icons/cube-outline.svg +1 -0
  216. package/icons/diagonal-arrow-left-down-outline.svg +1 -0
  217. package/icons/diagonal-arrow-left-up-outline.svg +1 -0
  218. package/icons/diagonal-arrow-right-down-outline.svg +1 -0
  219. package/icons/diagonal-arrow-right-up-outline.svg +1 -0
  220. package/icons/done-all-outline.svg +1 -0
  221. package/icons/download-outline.svg +1 -0
  222. package/icons/droplet-off-outline.svg +1 -0
  223. package/icons/droplet-outline.svg +1 -0
  224. package/icons/edit-2-outline.svg +1 -0
  225. package/icons/edit-outline.svg +1 -0
  226. package/icons/email-outline.svg +1 -0
  227. package/icons/expand-outline.svg +1 -0
  228. package/icons/external-link-outline.svg +1 -0
  229. package/icons/eye-off-2-outline.svg +1 -0
  230. package/icons/eye-off-outline.svg +1 -0
  231. package/icons/eye-outline.svg +1 -0
  232. package/icons/facebook-outline.svg +1 -0
  233. package/icons/file-add-outline.svg +1 -0
  234. package/icons/file-outline.svg +1 -0
  235. package/icons/file-remove-outline.svg +1 -0
  236. package/icons/file-text-outline.svg +1 -0
  237. package/icons/film-outline.svg +1 -0
  238. package/icons/flag-outline.svg +1 -0
  239. package/icons/flash-off-outline.svg +1 -0
  240. package/icons/flash-outline.svg +1 -0
  241. package/icons/flip-2-outline.svg +1 -0
  242. package/icons/flip-outline.svg +1 -0
  243. package/icons/folder-add-outline.svg +1 -0
  244. package/icons/folder-outline.svg +1 -0
  245. package/icons/folder-remove-outline.svg +1 -0
  246. package/icons/funnel-outline.svg +1 -0
  247. package/icons/gift-outline.svg +1 -0
  248. package/icons/github-outline.svg +1 -0
  249. package/icons/globe-2-outline.svg +1 -0
  250. package/icons/globe-outline.svg +1 -0
  251. package/icons/google-outline.svg +1 -0
  252. package/icons/grid-outline.svg +1 -0
  253. package/icons/hard-drive-outline.svg +1 -0
  254. package/icons/hash-outline.svg +1 -0
  255. package/icons/headphones-outline.svg +1 -0
  256. package/icons/heart-outline.svg +1 -0
  257. package/icons/home-outline.svg +1 -0
  258. package/icons/image-outline.svg +1 -0
  259. package/icons/inbox-outline.svg +1 -0
  260. package/icons/info-outline.svg +1 -0
  261. package/icons/keypad-outline.svg +1 -0
  262. package/icons/layers-outline.svg +1 -0
  263. package/icons/layout-outline.svg +1 -0
  264. package/icons/link-2-outline.svg +1 -0
  265. package/icons/link-outline.svg +1 -0
  266. package/icons/linkedin-outline.svg +1 -0
  267. package/icons/list-outline.svg +1 -0
  268. package/icons/loader-outline.svg +1 -0
  269. package/icons/lock-outline.svg +1 -0
  270. package/icons/log-in-outline.svg +1 -0
  271. package/icons/log-out-outline.svg +1 -0
  272. package/icons/map-outline.svg +1 -0
  273. package/icons/maximize-outline.svg +1 -0
  274. package/icons/menu-2-outline.svg +1 -0
  275. package/icons/menu-arrow-outline.svg +1 -0
  276. package/icons/menu-outline.svg +1 -0
  277. package/icons/message-circle-outline.svg +1 -0
  278. package/icons/message-square-outline.svg +1 -0
  279. package/icons/mic-off-outline.svg +1 -0
  280. package/icons/mic-outline.svg +1 -0
  281. package/icons/minimize-outline.svg +1 -0
  282. package/icons/minus-circle-outline.svg +1 -0
  283. package/icons/minus-outline.svg +1 -0
  284. package/icons/minus-square-outline.svg +1 -0
  285. package/icons/monitor-outline.svg +1 -0
  286. package/icons/moon-outline.svg +1 -0
  287. package/icons/more-horizontal-outline.svg +1 -0
  288. package/icons/more-vertical-outline.svg +1 -0
  289. package/icons/move-outline.svg +1 -0
  290. package/icons/music-outline.svg +1 -0
  291. package/icons/navigation-2-outline.svg +1 -0
  292. package/icons/navigation-outline.svg +1 -0
  293. package/icons/npm-outline.svg +1 -0
  294. package/icons/options-2-outline.svg +1 -0
  295. package/icons/options-outline.svg +1 -0
  296. package/icons/pantone-outline.svg +1 -0
  297. package/icons/paper-plane-outline.svg +1 -0
  298. package/icons/pause-circle-outline.svg +1 -0
  299. package/icons/people-outline.svg +1 -0
  300. package/icons/percent-outline.svg +1 -0
  301. package/icons/person-add-outline.svg +1 -0
  302. package/icons/person-delete-outline.svg +1 -0
  303. package/icons/person-done-outline.svg +1 -0
  304. package/icons/person-outline.svg +1 -0
  305. package/icons/person-remove-outline.svg +1 -0
  306. package/icons/phone-call-outline.svg +1 -0
  307. package/icons/phone-missed-outline.svg +1 -0
  308. package/icons/phone-off-outline.svg +1 -0
  309. package/icons/phone-outline.svg +1 -0
  310. package/icons/pie-chart-outline.svg +1 -0
  311. package/icons/pin-outline.svg +1 -0
  312. package/icons/play-circle-outline.svg +1 -0
  313. package/icons/plus-circle-outline.svg +1 -0
  314. package/icons/plus-outline.svg +1 -0
  315. package/icons/plus-square-outline.svg +1 -0
  316. package/icons/power-outline.svg +1 -0
  317. package/icons/pricetags-outline.svg +1 -0
  318. package/icons/printer-outline.svg +1 -0
  319. package/icons/question-mark-circle-outline.svg +1 -0
  320. package/icons/question-mark-outline.svg +1 -0
  321. package/icons/radio-button-off-outline.svg +1 -0
  322. package/icons/radio-button-on-outline.svg +1 -0
  323. package/icons/radio-outline.svg +1 -0
  324. package/icons/recording-outline.svg +1 -0
  325. package/icons/refresh-outline.svg +1 -0
  326. package/icons/repeat-outline.svg +1 -0
  327. package/icons/rewind-left-outline.svg +1 -0
  328. package/icons/rewind-right-outline.svg +1 -0
  329. package/icons/save-outline.svg +1 -0
  330. package/icons/scissors-outline.svg +1 -0
  331. package/icons/search-outline.svg +1 -0
  332. package/icons/settings-2-outline.svg +1 -0
  333. package/icons/settings-outline.svg +1 -0
  334. package/icons/shake-outline.svg +1 -0
  335. package/icons/share-outline.svg +1 -0
  336. package/icons/shield-off-outline.svg +1 -0
  337. package/icons/shield-outline.svg +1 -0
  338. package/icons/shopping-bag-outline.svg +1 -0
  339. package/icons/shopping-cart-outline.svg +1 -0
  340. package/icons/shuffle-2-outline.svg +1 -0
  341. package/icons/shuffle-outline.svg +1 -0
  342. package/icons/skip-back-outline.svg +1 -0
  343. package/icons/skip-forward-outline.svg +1 -0
  344. package/icons/slash-outline.svg +1 -0
  345. package/icons/smartphone-outline.svg +1 -0
  346. package/icons/smiling-face-outline.svg +1 -0
  347. package/icons/speaker-outline.svg +1 -0
  348. package/icons/square-outline.svg +1 -0
  349. package/icons/star-outline.svg +1 -0
  350. package/icons/stop-circle-outline.svg +1 -0
  351. package/icons/sun-outline.svg +1 -0
  352. package/icons/swap-outline.svg +1 -0
  353. package/icons/sync-outline.svg +1 -0
  354. package/icons/text-outline.svg +1 -0
  355. package/icons/thermometer-minus-outline.svg +1 -0
  356. package/icons/thermometer-outline.svg +1 -0
  357. package/icons/thermometer-plus-outline.svg +1 -0
  358. package/icons/toggle-left-outline.svg +1 -0
  359. package/icons/toggle-right-outline.svg +1 -0
  360. package/icons/trash-2-outline.svg +1 -0
  361. package/icons/trash-outline.svg +1 -0
  362. package/icons/trending-down-outline.svg +1 -0
  363. package/icons/trending-up-outline.svg +1 -0
  364. package/icons/tv-outline.svg +1 -0
  365. package/icons/twitter-outline.svg +1 -0
  366. package/icons/umbrella-outline.svg +1 -0
  367. package/icons/undo-outline.svg +1 -0
  368. package/icons/unlock-outline.svg +1 -0
  369. package/icons/upload-outline.svg +1 -0
  370. package/icons/video-off-outline.svg +1 -0
  371. package/icons/video-outline.svg +1 -0
  372. package/icons/volume-down-outline.svg +1 -0
  373. package/icons/volume-mute-outline.svg +1 -0
  374. package/icons/volume-off-outline.svg +1 -0
  375. package/icons/volume-up-outline.svg +1 -0
  376. package/icons/wifi-off-outline.svg +1 -0
  377. package/icons/wifi-outline.svg +1 -0
  378. package/js/carousel.js +133 -0
  379. package/js/carousel.ts +173 -0
  380. package/js/chart.js +257 -0
  381. package/js/code-viewer.js +148 -0
  382. package/js/code-viewer.ts +188 -0
  383. package/js/datepicker.js +497 -0
  384. package/js/datepicker.ts +619 -0
  385. package/js/dropdown.js +122 -0
  386. package/js/dropdown.ts +180 -0
  387. package/js/editor.js +421 -0
  388. package/js/editor.ts +426 -0
  389. package/js/file-uploader.js +268 -0
  390. package/js/file-uploader.ts +350 -0
  391. package/js/flyout-menu.js +195 -0
  392. package/js/flyout-menu.ts +250 -0
  393. package/js/form-builder.js +107 -0
  394. package/js/gallery.js +177 -0
  395. package/js/gallery.ts +231 -0
  396. package/js/guitar-chords.js +268 -0
  397. package/js/index.js +720 -0
  398. package/js/index.ts +874 -0
  399. package/js/lazy-loader.js +121 -0
  400. package/js/modal.js +113 -0
  401. package/js/modal.ts +167 -0
  402. package/js/push-menu.js +101 -0
  403. package/js/push-menu.ts +130 -0
  404. package/js/request.js +51 -0
  405. package/js/scroll.js +27 -0
  406. package/js/scroll.ts +47 -0
  407. package/js/scrollbar.js +219 -0
  408. package/js/scrollbar.ts +308 -0
  409. package/js/select.js +158 -0
  410. package/js/select.ts +217 -0
  411. package/js/table.js +359 -0
  412. package/js/table.ts +453 -0
  413. package/js/tabs.js +225 -0
  414. package/js/tabs.ts +280 -0
  415. package/js/theme.js +194 -0
  416. package/js/theme.ts +225 -0
  417. package/js/timepicker.js +98 -0
  418. package/js/timepicker.ts +131 -0
  419. package/js/toast.js +93 -0
  420. package/js/toast.ts +138 -0
  421. package/js/tooltip.js +193 -0
  422. package/js/tooltip.ts +252 -0
  423. package/js/tree.js +162 -0
  424. package/js/tree.ts +218 -0
  425. package/js/tsconfig.json +18 -0
  426. package/js/utils.js +69 -0
  427. package/js/utils.ts +84 -0
  428. package/js/virtual-dropdown.js +277 -0
  429. package/js/virtual-dropdown.ts +366 -0
  430. package/package.json +38 -0
package/js/table.js ADDED
@@ -0,0 +1,359 @@
1
+ import { Select } from "./select.js";
2
+ class Table {
3
+ constructor(elementOrSelector, options = {}) {
4
+ const element = typeof elementOrSelector === 'string'
5
+ ? document.querySelector(elementOrSelector)
6
+ : elementOrSelector;
7
+ if (!element) {
8
+ throw new Error(`Table: Element not found for selector "${elementOrSelector}"`);
9
+ }
10
+ this.container = element;
11
+ this.data = options.data || [];
12
+ this.columns = options.columns || [];
13
+ this.pageSize = options.pageSize || 10;
14
+ this.currentPage = 1;
15
+ this.sortColumn = null;
16
+ this.sortDirection = 'asc';
17
+ this.filterText = '';
18
+ if (this.data.length === 0 && this.container.querySelector('table')) {
19
+ this.parseTableFromDOM();
20
+ }
21
+ this.init();
22
+ }
23
+ /**
24
+ * Parses an existing HTML table in the DOM to extract data and columns
25
+ */
26
+ parseTableFromDOM() {
27
+ const table = this.container.querySelector('table');
28
+ if (!table)
29
+ return;
30
+ const thead = table.querySelector('thead');
31
+ const tbody = table.querySelector('tbody');
32
+ if (!thead || !tbody)
33
+ return;
34
+ // Parse columns from header
35
+ const ths = thead.querySelectorAll('th');
36
+ this.columns = Array.from(ths).map((th, index) => ({
37
+ key: `col${index}`,
38
+ label: th.textContent?.trim() || '',
39
+ sortable: true
40
+ }));
41
+ // Parse data from body rows
42
+ const trs = tbody.querySelectorAll('tr');
43
+ this.data = Array.from(trs).map(tr => {
44
+ const row = {};
45
+ const tds = tr.querySelectorAll('td');
46
+ tds.forEach((td, index) => {
47
+ if (this.columns[index]) {
48
+ row[this.columns[index].key] = td.textContent?.trim() || '';
49
+ }
50
+ });
51
+ return row;
52
+ });
53
+ // Clear the existing static table
54
+ this.container.innerHTML = '';
55
+ }
56
+ /**
57
+ * Initializes the table by rendering controls, structure, and content
58
+ */
59
+ init() {
60
+ this.renderControls();
61
+ this.renderTableStructure();
62
+ this.render();
63
+ }
64
+ /**
65
+ * Renders the search and page size controls
66
+ */
67
+ renderControls() {
68
+ const controlsDiv = document.createElement('div');
69
+ controlsDiv.className = 'table-controls';
70
+ // Search input
71
+ const searchInput = document.createElement('input');
72
+ searchInput.type = 'text';
73
+ searchInput.placeholder = 'Search...';
74
+ searchInput.className = 'search-input';
75
+ searchInput.addEventListener('input', (e) => {
76
+ this.handleSearch(e.target.value);
77
+ });
78
+ controlsDiv.appendChild(searchInput);
79
+ // Page size selector
80
+ const selectGroup = document.createElement('div');
81
+ selectGroup.className = 'select-group';
82
+ const label = document.createElement('label');
83
+ label.textContent = 'Page Size';
84
+ selectGroup.appendChild(label);
85
+ const pageSizeSelect = document.createElement('select');
86
+ pageSizeSelect.className = 'page-size-select';
87
+ [5, 10, 20, 50].forEach(size => {
88
+ const option = document.createElement('option');
89
+ option.value = String(size);
90
+ option.textContent = `${size} per page`;
91
+ option.selected = size === this.pageSize;
92
+ pageSizeSelect.appendChild(option);
93
+ });
94
+ pageSizeSelect.addEventListener('change', (e) => {
95
+ this.handlePageSizeChange(parseInt(e.target.value, 10));
96
+ });
97
+ this.assignUniqueId(pageSizeSelect, 'page-size-select-0');
98
+ selectGroup.appendChild(pageSizeSelect);
99
+ controlsDiv.appendChild(selectGroup);
100
+ this.container.appendChild(controlsDiv);
101
+ new Select('#' + pageSizeSelect.id);
102
+ }
103
+ /**
104
+ * Creates the table structure (table, thead, tbody, pagination container)
105
+ */
106
+ renderTableStructure() {
107
+ const wrapper = document.createElement('div');
108
+ wrapper.className = 'table-wrapper';
109
+ const table = document.createElement('table');
110
+ const thead = document.createElement('thead');
111
+ const tbody = document.createElement('tbody');
112
+ // Create header row
113
+ const tr = document.createElement('tr');
114
+ this.columns.forEach(col => {
115
+ const th = document.createElement('th');
116
+ th.textContent = col.label;
117
+ th.dataset.key = col.key;
118
+ if (col.sortable !== false) {
119
+ th.classList.add('sortable');
120
+ th.addEventListener('click', () => this.handleSort(col.key));
121
+ }
122
+ tr.appendChild(th);
123
+ });
124
+ thead.appendChild(tr);
125
+ table.appendChild(thead);
126
+ table.appendChild(tbody);
127
+ wrapper.appendChild(table);
128
+ this.container.appendChild(wrapper);
129
+ // Create pagination container
130
+ const paginationDiv = document.createElement('div');
131
+ paginationDiv.className = 'pagination';
132
+ this.container.appendChild(paginationDiv);
133
+ this.tableBody = tbody;
134
+ this.tableHeader = thead;
135
+ this.paginationContainer = paginationDiv;
136
+ }
137
+ /**
138
+ * Returns filtered and sorted data based on current state
139
+ */
140
+ getFilteredAndSortedData() {
141
+ let processedData = [...this.data];
142
+ // Apply filter
143
+ if (this.filterText) {
144
+ const lowerFilter = this.filterText.toLowerCase();
145
+ processedData = processedData.filter(row => {
146
+ return this.columns.some(col => {
147
+ const val = String(row[col.key] ?? '').toLowerCase();
148
+ return val.includes(lowerFilter);
149
+ });
150
+ });
151
+ }
152
+ // Apply sort
153
+ if (this.sortColumn) {
154
+ processedData.sort((a, b) => {
155
+ const valA = a[this.sortColumn];
156
+ const valB = b[this.sortColumn];
157
+ // Handle null/undefined values
158
+ if (valA == null && valB == null)
159
+ return 0;
160
+ if (valA == null)
161
+ return 1;
162
+ if (valB == null)
163
+ return -1;
164
+ if (valA < valB)
165
+ return this.sortDirection === 'asc' ? -1 : 1;
166
+ if (valA > valB)
167
+ return this.sortDirection === 'asc' ? 1 : -1;
168
+ return 0;
169
+ });
170
+ }
171
+ return processedData;
172
+ }
173
+ /**
174
+ * Renders the table body, pagination, and header sort indicators
175
+ */
176
+ render() {
177
+ const processedData = this.getFilteredAndSortedData();
178
+ const totalItems = processedData.length;
179
+ const totalPages = Math.ceil(totalItems / this.pageSize);
180
+ // Ensure current page is valid
181
+ if (this.currentPage > totalPages && totalPages > 0) {
182
+ this.currentPage = totalPages;
183
+ }
184
+ if (this.currentPage < 1 && totalPages > 0) {
185
+ this.currentPage = 1;
186
+ }
187
+ const startIndex = (this.currentPage - 1) * this.pageSize;
188
+ const endIndex = Math.min(startIndex + this.pageSize, totalItems);
189
+ const pageData = processedData.slice(startIndex, endIndex);
190
+ this.renderBody(pageData);
191
+ this.renderPagination(totalItems, totalPages, startIndex, endIndex);
192
+ this.updateHeaderSortIcons();
193
+ }
194
+ /**
195
+ * Renders the table body rows
196
+ */
197
+ renderBody(data) {
198
+ this.tableBody.innerHTML = '';
199
+ if (data.length === 0) {
200
+ const tr = document.createElement('tr');
201
+ const td = document.createElement('td');
202
+ td.colSpan = this.columns.length;
203
+ td.textContent = 'No results found';
204
+ td.style.textAlign = 'center';
205
+ tr.appendChild(td);
206
+ this.tableBody.appendChild(tr);
207
+ return;
208
+ }
209
+ data.forEach(row => {
210
+ const tr = document.createElement('tr');
211
+ this.columns.forEach(col => {
212
+ const td = document.createElement('td');
213
+ td.textContent = String(row[col.key] ?? '');
214
+ td.setAttribute('data-label', col.label); // For mobile view
215
+ tr.appendChild(td);
216
+ });
217
+ this.tableBody.appendChild(tr);
218
+ });
219
+ }
220
+ /**
221
+ * Updates the sort direction indicators in table headers
222
+ */
223
+ updateHeaderSortIcons() {
224
+ const ths = this.tableHeader.querySelectorAll('th');
225
+ ths.forEach(th => {
226
+ th.classList.remove('sort-asc', 'sort-desc');
227
+ if (th.dataset.key === this.sortColumn) {
228
+ th.classList.add(this.sortDirection === 'asc' ? 'sort-asc' : 'sort-desc');
229
+ }
230
+ });
231
+ }
232
+ /**
233
+ * Renders pagination controls and info
234
+ */
235
+ renderPagination(totalItems, totalPages, startIndex, endIndex) {
236
+ this.paginationContainer.innerHTML = '';
237
+ if (totalItems === 0)
238
+ return;
239
+ // Info text
240
+ const info = document.createElement('div');
241
+ info.className = 'pagination-info';
242
+ info.textContent = `Showing ${startIndex + 1} to ${endIndex} of ${totalItems} entries`;
243
+ this.paginationContainer.appendChild(info);
244
+ // Pagination buttons
245
+ const buttonsDiv = document.createElement('div');
246
+ buttonsDiv.className = 'pagination-buttons';
247
+ // Previous button
248
+ const prevBtn = document.createElement('button');
249
+ prevBtn.className = 'page-btn';
250
+ prevBtn.textContent = 'Previous';
251
+ prevBtn.disabled = this.currentPage === 1;
252
+ prevBtn.addEventListener('click', () => this.setPage(this.currentPage - 1));
253
+ buttonsDiv.appendChild(prevBtn);
254
+ // Calculate page range to display (max 5 pages)
255
+ let startPage = Math.max(1, this.currentPage - 2);
256
+ let endPage = Math.min(totalPages, startPage + 4);
257
+ if (endPage - startPage < 4) {
258
+ startPage = Math.max(1, endPage - 4);
259
+ }
260
+ // Page number buttons
261
+ for (let i = startPage; i <= endPage; i++) {
262
+ const btn = document.createElement('button');
263
+ btn.className = `page-btn ${i === this.currentPage ? 'active' : ''}`;
264
+ btn.textContent = String(i);
265
+ btn.addEventListener('click', () => this.setPage(i));
266
+ buttonsDiv.appendChild(btn);
267
+ }
268
+ // Next button
269
+ const nextBtn = document.createElement('button');
270
+ nextBtn.className = 'page-btn';
271
+ nextBtn.textContent = 'Next';
272
+ nextBtn.disabled = this.currentPage === totalPages;
273
+ nextBtn.addEventListener('click', () => this.setPage(this.currentPage + 1));
274
+ buttonsDiv.appendChild(nextBtn);
275
+ this.paginationContainer.appendChild(buttonsDiv);
276
+ }
277
+ /**
278
+ * Handles search input changes
279
+ */
280
+ handleSearch(text) {
281
+ this.filterText = text;
282
+ this.currentPage = 1; // Reset to first page on search
283
+ this.render();
284
+ }
285
+ /**
286
+ * Handles column header clicks for sorting
287
+ */
288
+ handleSort(key) {
289
+ if (this.sortColumn === key) {
290
+ // Toggle sort direction
291
+ this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
292
+ }
293
+ else {
294
+ this.sortColumn = key;
295
+ this.sortDirection = 'asc';
296
+ }
297
+ this.render();
298
+ }
299
+ /**
300
+ * Handles page size changes
301
+ */
302
+ handlePageSizeChange(size) {
303
+ this.pageSize = size;
304
+ this.currentPage = 1;
305
+ this.render();
306
+ }
307
+ /**
308
+ * Sets the current page and re-renders
309
+ */
310
+ setPage(page) {
311
+ this.currentPage = page;
312
+ this.render();
313
+ }
314
+ /**
315
+ * Assigns a unique ID to an element, incrementing if necessary
316
+ */
317
+ assignUniqueId(element, baseId) {
318
+ if (!element || !baseId)
319
+ return null;
320
+ let id = baseId;
321
+ let counter = 1;
322
+ // If baseId already ends with a number, extract it
323
+ const match = baseId.match(/^(.*?)(\d+)$/);
324
+ if (match) {
325
+ id = match[1];
326
+ counter = parseInt(match[2], 10);
327
+ }
328
+ let uniqueId = baseId;
329
+ while (document.getElementById(uniqueId)) {
330
+ counter++;
331
+ uniqueId = `${id}${counter}`;
332
+ }
333
+ element.id = uniqueId;
334
+ return uniqueId;
335
+ }
336
+ /**
337
+ * Public API: Updates the table data and re-renders
338
+ */
339
+ setData(data) {
340
+ this.data = data;
341
+ this.currentPage = 1;
342
+ this.render();
343
+ }
344
+ /**
345
+ * Public API: Updates the columns and re-renders
346
+ */
347
+ setColumns(columns) {
348
+ this.columns = columns;
349
+ this.container.innerHTML = '';
350
+ this.init();
351
+ }
352
+ /**
353
+ * Public API: Gets the current filtered and sorted data
354
+ */
355
+ getData() {
356
+ return this.getFilteredAndSortedData();
357
+ }
358
+ }
359
+ export { Table };