@keenthemes/ktui 1.0.3

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 (426) hide show
  1. package/CONTRIBUTING.md +88 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +124 -0
  4. package/dist/ktui.js +19201 -0
  5. package/dist/ktui.min.js +2 -0
  6. package/dist/ktui.min.js.map +1 -0
  7. package/lib/cjs/components/accordion/accordion.js +168 -0
  8. package/lib/cjs/components/accordion/accordion.js.map +1 -0
  9. package/lib/cjs/components/accordion/index.js +6 -0
  10. package/lib/cjs/components/accordion/index.js.map +1 -0
  11. package/lib/cjs/components/accordion/types.js +3 -0
  12. package/lib/cjs/components/accordion/types.js.map +1 -0
  13. package/lib/cjs/components/collapse/collapse.js +169 -0
  14. package/lib/cjs/components/collapse/collapse.js.map +1 -0
  15. package/lib/cjs/components/collapse/index.js +6 -0
  16. package/lib/cjs/components/collapse/index.js.map +1 -0
  17. package/lib/cjs/components/collapse/types.js +3 -0
  18. package/lib/cjs/components/collapse/types.js.map +1 -0
  19. package/lib/cjs/components/component.js +135 -0
  20. package/lib/cjs/components/component.js.map +1 -0
  21. package/lib/cjs/components/config.js +26 -0
  22. package/lib/cjs/components/config.js.map +1 -0
  23. package/lib/cjs/components/config.umd.js +23 -0
  24. package/lib/cjs/components/config.umd.js.map +1 -0
  25. package/lib/cjs/components/constants.js +15 -0
  26. package/lib/cjs/components/constants.js.map +1 -0
  27. package/lib/cjs/components/datatable/datatable.js +1464 -0
  28. package/lib/cjs/components/datatable/datatable.js.map +1 -0
  29. package/lib/cjs/components/datatable/index.js +6 -0
  30. package/lib/cjs/components/datatable/index.js.map +1 -0
  31. package/lib/cjs/components/datatable/types.js +3 -0
  32. package/lib/cjs/components/datatable/types.js.map +1 -0
  33. package/lib/cjs/components/dismiss/dismiss.js +131 -0
  34. package/lib/cjs/components/dismiss/dismiss.js.map +1 -0
  35. package/lib/cjs/components/dismiss/index.js +6 -0
  36. package/lib/cjs/components/dismiss/index.js.map +1 -0
  37. package/lib/cjs/components/dismiss/types.js +3 -0
  38. package/lib/cjs/components/dismiss/types.js.map +1 -0
  39. package/lib/cjs/components/drawer/drawer.js +347 -0
  40. package/lib/cjs/components/drawer/drawer.js.map +1 -0
  41. package/lib/cjs/components/drawer/index.js +6 -0
  42. package/lib/cjs/components/drawer/index.js.map +1 -0
  43. package/lib/cjs/components/drawer/types.js +3 -0
  44. package/lib/cjs/components/drawer/types.js.map +1 -0
  45. package/lib/cjs/components/dropdown/dropdown.js +403 -0
  46. package/lib/cjs/components/dropdown/dropdown.js.map +1 -0
  47. package/lib/cjs/components/dropdown/index.js +6 -0
  48. package/lib/cjs/components/dropdown/index.js.map +1 -0
  49. package/lib/cjs/components/dropdown/types.js +3 -0
  50. package/lib/cjs/components/dropdown/types.js.map +1 -0
  51. package/lib/cjs/components/image-input/image-input.js +191 -0
  52. package/lib/cjs/components/image-input/image-input.js.map +1 -0
  53. package/lib/cjs/components/image-input/index.js +6 -0
  54. package/lib/cjs/components/image-input/index.js.map +1 -0
  55. package/lib/cjs/components/image-input/types.js +3 -0
  56. package/lib/cjs/components/image-input/types.js.map +1 -0
  57. package/lib/cjs/components/menu/index.js +6 -0
  58. package/lib/cjs/components/menu/index.js.map +1 -0
  59. package/lib/cjs/components/menu/menu.js +1021 -0
  60. package/lib/cjs/components/menu/menu.js.map +1 -0
  61. package/lib/cjs/components/menu/types.js +3 -0
  62. package/lib/cjs/components/menu/types.js.map +1 -0
  63. package/lib/cjs/components/modal/index.js +6 -0
  64. package/lib/cjs/components/modal/index.js.map +1 -0
  65. package/lib/cjs/components/modal/modal.js +316 -0
  66. package/lib/cjs/components/modal/modal.js.map +1 -0
  67. package/lib/cjs/components/modal/types.js +3 -0
  68. package/lib/cjs/components/modal/types.js.map +1 -0
  69. package/lib/cjs/components/reparent/index.js +6 -0
  70. package/lib/cjs/components/reparent/index.js.map +1 -0
  71. package/lib/cjs/components/reparent/reparent.js +93 -0
  72. package/lib/cjs/components/reparent/reparent.js.map +1 -0
  73. package/lib/cjs/components/reparent/types.js +3 -0
  74. package/lib/cjs/components/reparent/types.js.map +1 -0
  75. package/lib/cjs/components/scrollable/index.js +6 -0
  76. package/lib/cjs/components/scrollable/index.js.map +1 -0
  77. package/lib/cjs/components/scrollable/scrollable.js +259 -0
  78. package/lib/cjs/components/scrollable/scrollable.js.map +1 -0
  79. package/lib/cjs/components/scrollable/types.js +3 -0
  80. package/lib/cjs/components/scrollable/types.js.map +1 -0
  81. package/lib/cjs/components/scrollspy/index.js +6 -0
  82. package/lib/cjs/components/scrollspy/index.js.map +1 -0
  83. package/lib/cjs/components/scrollspy/scrollspy.js +174 -0
  84. package/lib/cjs/components/scrollspy/scrollspy.js.map +1 -0
  85. package/lib/cjs/components/scrollspy/types.js +3 -0
  86. package/lib/cjs/components/scrollspy/types.js.map +1 -0
  87. package/lib/cjs/components/scrollto/index.js +6 -0
  88. package/lib/cjs/components/scrollto/index.js.map +1 -0
  89. package/lib/cjs/components/scrollto/scrollto.js +103 -0
  90. package/lib/cjs/components/scrollto/scrollto.js.map +1 -0
  91. package/lib/cjs/components/scrollto/types.js +3 -0
  92. package/lib/cjs/components/scrollto/types.js.map +1 -0
  93. package/lib/cjs/components/stepper/index.js +6 -0
  94. package/lib/cjs/components/stepper/index.js.map +1 -0
  95. package/lib/cjs/components/stepper/stepper.js +258 -0
  96. package/lib/cjs/components/stepper/stepper.js.map +1 -0
  97. package/lib/cjs/components/stepper/types.js +3 -0
  98. package/lib/cjs/components/stepper/types.js.map +1 -0
  99. package/lib/cjs/components/sticky/index.js +6 -0
  100. package/lib/cjs/components/sticky/index.js.map +1 -0
  101. package/lib/cjs/components/sticky/sticky.js +297 -0
  102. package/lib/cjs/components/sticky/sticky.js.map +1 -0
  103. package/lib/cjs/components/sticky/types.js +3 -0
  104. package/lib/cjs/components/sticky/types.js.map +1 -0
  105. package/lib/cjs/components/tabs/index.js +6 -0
  106. package/lib/cjs/components/tabs/index.js.map +1 -0
  107. package/lib/cjs/components/tabs/tabs.js +146 -0
  108. package/lib/cjs/components/tabs/tabs.js.map +1 -0
  109. package/lib/cjs/components/tabs/types.js +3 -0
  110. package/lib/cjs/components/tabs/types.js.map +1 -0
  111. package/lib/cjs/components/theme/index.js +6 -0
  112. package/lib/cjs/components/theme/index.js.map +1 -0
  113. package/lib/cjs/components/theme/theme.js +147 -0
  114. package/lib/cjs/components/theme/theme.js.map +1 -0
  115. package/lib/cjs/components/theme/types.js +3 -0
  116. package/lib/cjs/components/theme/types.js.map +1 -0
  117. package/lib/cjs/components/toggle/index.js +6 -0
  118. package/lib/cjs/components/toggle/index.js.map +1 -0
  119. package/lib/cjs/components/toggle/toggle.js +139 -0
  120. package/lib/cjs/components/toggle/toggle.js.map +1 -0
  121. package/lib/cjs/components/toggle/types.js +3 -0
  122. package/lib/cjs/components/toggle/types.js.map +1 -0
  123. package/lib/cjs/components/toggle-password/index.js +6 -0
  124. package/lib/cjs/components/toggle-password/index.js.map +1 -0
  125. package/lib/cjs/components/toggle-password/toggle-password.js +131 -0
  126. package/lib/cjs/components/toggle-password/toggle-password.js.map +1 -0
  127. package/lib/cjs/components/toggle-password/types.js +3 -0
  128. package/lib/cjs/components/toggle-password/types.js.map +1 -0
  129. package/lib/cjs/components/tooltip/index.js +6 -0
  130. package/lib/cjs/components/tooltip/index.js.map +1 -0
  131. package/lib/cjs/components/tooltip/tooltip.js +271 -0
  132. package/lib/cjs/components/tooltip/tooltip.js.map +1 -0
  133. package/lib/cjs/components/tooltip/types.js +3 -0
  134. package/lib/cjs/components/tooltip/types.js.map +1 -0
  135. package/lib/cjs/helpers/data.js +33 -0
  136. package/lib/cjs/helpers/data.js.map +1 -0
  137. package/lib/cjs/helpers/dom.js +297 -0
  138. package/lib/cjs/helpers/dom.js.map +1 -0
  139. package/lib/cjs/helpers/event-handler.js +36 -0
  140. package/lib/cjs/helpers/event-handler.js.map +1 -0
  141. package/lib/cjs/helpers/utils.js +94 -0
  142. package/lib/cjs/helpers/utils.js.map +1 -0
  143. package/lib/cjs/index.js +105 -0
  144. package/lib/cjs/index.js.map +1 -0
  145. package/lib/cjs/types.js +3 -0
  146. package/lib/cjs/types.js.map +1 -0
  147. package/lib/esm/components/accordion/accordion.js +165 -0
  148. package/lib/esm/components/accordion/accordion.js.map +1 -0
  149. package/lib/esm/components/accordion/index.js +2 -0
  150. package/lib/esm/components/accordion/index.js.map +1 -0
  151. package/lib/esm/components/accordion/types.js +2 -0
  152. package/lib/esm/components/accordion/types.js.map +1 -0
  153. package/lib/esm/components/collapse/collapse.js +166 -0
  154. package/lib/esm/components/collapse/collapse.js.map +1 -0
  155. package/lib/esm/components/collapse/index.js +2 -0
  156. package/lib/esm/components/collapse/index.js.map +1 -0
  157. package/lib/esm/components/collapse/types.js +2 -0
  158. package/lib/esm/components/collapse/types.js.map +1 -0
  159. package/lib/esm/components/component.js +133 -0
  160. package/lib/esm/components/component.js.map +1 -0
  161. package/lib/esm/components/config.js +24 -0
  162. package/lib/esm/components/config.js.map +1 -0
  163. package/lib/esm/components/config.umd.js +23 -0
  164. package/lib/esm/components/config.umd.js.map +1 -0
  165. package/lib/esm/components/constants.js +12 -0
  166. package/lib/esm/components/constants.js.map +1 -0
  167. package/lib/esm/components/datatable/datatable.js +1461 -0
  168. package/lib/esm/components/datatable/datatable.js.map +1 -0
  169. package/lib/esm/components/datatable/index.js +2 -0
  170. package/lib/esm/components/datatable/index.js.map +1 -0
  171. package/lib/esm/components/datatable/types.js +2 -0
  172. package/lib/esm/components/datatable/types.js.map +1 -0
  173. package/lib/esm/components/dismiss/dismiss.js +128 -0
  174. package/lib/esm/components/dismiss/dismiss.js.map +1 -0
  175. package/lib/esm/components/dismiss/index.js +2 -0
  176. package/lib/esm/components/dismiss/index.js.map +1 -0
  177. package/lib/esm/components/dismiss/types.js +2 -0
  178. package/lib/esm/components/dismiss/types.js.map +1 -0
  179. package/lib/esm/components/drawer/drawer.js +344 -0
  180. package/lib/esm/components/drawer/drawer.js.map +1 -0
  181. package/lib/esm/components/drawer/index.js +2 -0
  182. package/lib/esm/components/drawer/index.js.map +1 -0
  183. package/lib/esm/components/drawer/types.js +2 -0
  184. package/lib/esm/components/drawer/types.js.map +1 -0
  185. package/lib/esm/components/dropdown/dropdown.js +400 -0
  186. package/lib/esm/components/dropdown/dropdown.js.map +1 -0
  187. package/lib/esm/components/dropdown/index.js +2 -0
  188. package/lib/esm/components/dropdown/index.js.map +1 -0
  189. package/lib/esm/components/dropdown/types.js +2 -0
  190. package/lib/esm/components/dropdown/types.js.map +1 -0
  191. package/lib/esm/components/image-input/image-input.js +188 -0
  192. package/lib/esm/components/image-input/image-input.js.map +1 -0
  193. package/lib/esm/components/image-input/index.js +2 -0
  194. package/lib/esm/components/image-input/index.js.map +1 -0
  195. package/lib/esm/components/image-input/types.js +2 -0
  196. package/lib/esm/components/image-input/types.js.map +1 -0
  197. package/lib/esm/components/menu/index.js +2 -0
  198. package/lib/esm/components/menu/index.js.map +1 -0
  199. package/lib/esm/components/menu/menu.js +1018 -0
  200. package/lib/esm/components/menu/menu.js.map +1 -0
  201. package/lib/esm/components/menu/types.js +2 -0
  202. package/lib/esm/components/menu/types.js.map +1 -0
  203. package/lib/esm/components/modal/index.js +2 -0
  204. package/lib/esm/components/modal/index.js.map +1 -0
  205. package/lib/esm/components/modal/modal.js +313 -0
  206. package/lib/esm/components/modal/modal.js.map +1 -0
  207. package/lib/esm/components/modal/types.js +2 -0
  208. package/lib/esm/components/modal/types.js.map +1 -0
  209. package/lib/esm/components/reparent/index.js +2 -0
  210. package/lib/esm/components/reparent/index.js.map +1 -0
  211. package/lib/esm/components/reparent/reparent.js +90 -0
  212. package/lib/esm/components/reparent/reparent.js.map +1 -0
  213. package/lib/esm/components/reparent/types.js +2 -0
  214. package/lib/esm/components/reparent/types.js.map +1 -0
  215. package/lib/esm/components/scrollable/index.js +2 -0
  216. package/lib/esm/components/scrollable/index.js.map +1 -0
  217. package/lib/esm/components/scrollable/scrollable.js +256 -0
  218. package/lib/esm/components/scrollable/scrollable.js.map +1 -0
  219. package/lib/esm/components/scrollable/types.js +2 -0
  220. package/lib/esm/components/scrollable/types.js.map +1 -0
  221. package/lib/esm/components/scrollspy/index.js +2 -0
  222. package/lib/esm/components/scrollspy/index.js.map +1 -0
  223. package/lib/esm/components/scrollspy/scrollspy.js +171 -0
  224. package/lib/esm/components/scrollspy/scrollspy.js.map +1 -0
  225. package/lib/esm/components/scrollspy/types.js +2 -0
  226. package/lib/esm/components/scrollspy/types.js.map +1 -0
  227. package/lib/esm/components/scrollto/index.js +2 -0
  228. package/lib/esm/components/scrollto/index.js.map +1 -0
  229. package/lib/esm/components/scrollto/scrollto.js +100 -0
  230. package/lib/esm/components/scrollto/scrollto.js.map +1 -0
  231. package/lib/esm/components/scrollto/types.js +2 -0
  232. package/lib/esm/components/scrollto/types.js.map +1 -0
  233. package/lib/esm/components/stepper/index.js +2 -0
  234. package/lib/esm/components/stepper/index.js.map +1 -0
  235. package/lib/esm/components/stepper/stepper.js +255 -0
  236. package/lib/esm/components/stepper/stepper.js.map +1 -0
  237. package/lib/esm/components/stepper/types.js +2 -0
  238. package/lib/esm/components/stepper/types.js.map +1 -0
  239. package/lib/esm/components/sticky/index.js +2 -0
  240. package/lib/esm/components/sticky/index.js.map +1 -0
  241. package/lib/esm/components/sticky/sticky.js +294 -0
  242. package/lib/esm/components/sticky/sticky.js.map +1 -0
  243. package/lib/esm/components/sticky/types.js +2 -0
  244. package/lib/esm/components/sticky/types.js.map +1 -0
  245. package/lib/esm/components/tabs/index.js +2 -0
  246. package/lib/esm/components/tabs/index.js.map +1 -0
  247. package/lib/esm/components/tabs/tabs.js +143 -0
  248. package/lib/esm/components/tabs/tabs.js.map +1 -0
  249. package/lib/esm/components/tabs/types.js +2 -0
  250. package/lib/esm/components/tabs/types.js.map +1 -0
  251. package/lib/esm/components/theme/index.js +2 -0
  252. package/lib/esm/components/theme/index.js.map +1 -0
  253. package/lib/esm/components/theme/theme.js +144 -0
  254. package/lib/esm/components/theme/theme.js.map +1 -0
  255. package/lib/esm/components/theme/types.js +2 -0
  256. package/lib/esm/components/theme/types.js.map +1 -0
  257. package/lib/esm/components/toggle/index.js +2 -0
  258. package/lib/esm/components/toggle/index.js.map +1 -0
  259. package/lib/esm/components/toggle/toggle.js +136 -0
  260. package/lib/esm/components/toggle/toggle.js.map +1 -0
  261. package/lib/esm/components/toggle/types.js +2 -0
  262. package/lib/esm/components/toggle/types.js.map +1 -0
  263. package/lib/esm/components/toggle-password/index.js +2 -0
  264. package/lib/esm/components/toggle-password/index.js.map +1 -0
  265. package/lib/esm/components/toggle-password/toggle-password.js +128 -0
  266. package/lib/esm/components/toggle-password/toggle-password.js.map +1 -0
  267. package/lib/esm/components/toggle-password/types.js +2 -0
  268. package/lib/esm/components/toggle-password/types.js.map +1 -0
  269. package/lib/esm/components/tooltip/index.js +2 -0
  270. package/lib/esm/components/tooltip/index.js.map +1 -0
  271. package/lib/esm/components/tooltip/tooltip.js +268 -0
  272. package/lib/esm/components/tooltip/tooltip.js.map +1 -0
  273. package/lib/esm/components/tooltip/types.js +2 -0
  274. package/lib/esm/components/tooltip/types.js.map +1 -0
  275. package/lib/esm/helpers/data.js +31 -0
  276. package/lib/esm/helpers/data.js.map +1 -0
  277. package/lib/esm/helpers/dom.js +295 -0
  278. package/lib/esm/helpers/dom.js.map +1 -0
  279. package/lib/esm/helpers/event-handler.js +34 -0
  280. package/lib/esm/helpers/event-handler.js.map +1 -0
  281. package/lib/esm/helpers/utils.js +92 -0
  282. package/lib/esm/helpers/utils.js.map +1 -0
  283. package/lib/esm/index.js +79 -0
  284. package/lib/esm/index.js.map +1 -0
  285. package/lib/esm/types.js +2 -0
  286. package/lib/esm/types.js.map +1 -0
  287. package/package.json +85 -0
  288. package/prettier.config.js +9 -0
  289. package/src/components/accordion/accordion-menu.css +51 -0
  290. package/src/components/accordion/accordion.css +86 -0
  291. package/src/components/accordion/accordion.ts +221 -0
  292. package/src/components/accordion/index.ts +7 -0
  293. package/src/components/accordion/types.ts +16 -0
  294. package/src/components/alert/alert.css +282 -0
  295. package/src/components/avatar/avatar.css +46 -0
  296. package/src/components/badge/badge.css +176 -0
  297. package/src/components/breadcrumb/breadcrumb.css +38 -0
  298. package/src/components/btn/btn.css +227 -0
  299. package/src/components/card/card.css +158 -0
  300. package/src/components/checkbox/checkbox.css +74 -0
  301. package/src/components/collapse/collapse.css +14 -0
  302. package/src/components/collapse/collapse.ts +200 -0
  303. package/src/components/collapse/index.ts +7 -0
  304. package/src/components/collapse/types.ts +16 -0
  305. package/src/components/component.ts +132 -0
  306. package/src/components/constants.ts +16 -0
  307. package/src/components/datatable/datatable-checkbox.ts +236 -0
  308. package/src/components/datatable/datatable-sort.ts +154 -0
  309. package/src/components/datatable/datatable.css +110 -0
  310. package/src/components/datatable/datatable.ts +1657 -0
  311. package/src/components/datatable/index.ts +19 -0
  312. package/src/components/datatable/types.ts +203 -0
  313. package/src/components/datepicker/calendar.ts +1397 -0
  314. package/src/components/datepicker/config.ts +368 -0
  315. package/src/components/datepicker/datepicker.css +7 -0
  316. package/src/components/datepicker/datepicker.ts +1287 -0
  317. package/src/components/datepicker/dropdown.ts +757 -0
  318. package/src/components/datepicker/events.ts +149 -0
  319. package/src/components/datepicker/index.ts +10 -0
  320. package/src/components/datepicker/keyboard.ts +646 -0
  321. package/src/components/datepicker/locales.ts +80 -0
  322. package/src/components/datepicker/templates.ts +792 -0
  323. package/src/components/datepicker/types.ts +154 -0
  324. package/src/components/datepicker/utils.ts +631 -0
  325. package/src/components/dismiss/dismiss.css +10 -0
  326. package/src/components/dismiss/dismiss.ts +152 -0
  327. package/src/components/dismiss/index.ts +7 -0
  328. package/src/components/dismiss/types.ts +17 -0
  329. package/src/components/drawer/drawer.css +97 -0
  330. package/src/components/drawer/drawer.ts +437 -0
  331. package/src/components/drawer/index.ts +7 -0
  332. package/src/components/drawer/types.ts +25 -0
  333. package/src/components/dropdown/dropdown-menu.css +56 -0
  334. package/src/components/dropdown/dropdown.css +46 -0
  335. package/src/components/dropdown/dropdown.ts +549 -0
  336. package/src/components/dropdown/index.ts +7 -0
  337. package/src/components/dropdown/types.ts +28 -0
  338. package/src/components/form/form.css +54 -0
  339. package/src/components/image-input/image-input.css +56 -0
  340. package/src/components/image-input/image-input.ts +249 -0
  341. package/src/components/image-input/index.ts +10 -0
  342. package/src/components/image-input/types.ts +12 -0
  343. package/src/components/input/input-group.css +42 -0
  344. package/src/components/input/input.css +136 -0
  345. package/src/components/kbd/kbd.css +30 -0
  346. package/src/components/label/label.css +20 -0
  347. package/src/components/link/link.css +81 -0
  348. package/src/components/modal/index.ts +7 -0
  349. package/src/components/modal/modal.css +73 -0
  350. package/src/components/modal/modal.ts +382 -0
  351. package/src/components/modal/types.ts +21 -0
  352. package/src/components/pagination/pagination.css +26 -0
  353. package/src/components/popover/popover.css +22 -0
  354. package/src/components/progress/progress.css +51 -0
  355. package/src/components/radio/radio.css +51 -0
  356. package/src/components/reparent/index.ts +7 -0
  357. package/src/components/reparent/reparent.ts +109 -0
  358. package/src/components/reparent/types.ts +15 -0
  359. package/src/components/scrollable/index.ts +10 -0
  360. package/src/components/scrollable/scrollable.css +29 -0
  361. package/src/components/scrollable/scrollable.ts +297 -0
  362. package/src/components/scrollable/types.ts +16 -0
  363. package/src/components/scrollspy/index.ts +7 -0
  364. package/src/components/scrollspy/scrollspy.css +13 -0
  365. package/src/components/scrollspy/scrollspy.ts +224 -0
  366. package/src/components/scrollspy/types.ts +15 -0
  367. package/src/components/scrollto/index.ts +7 -0
  368. package/src/components/scrollto/scrollto.ts +127 -0
  369. package/src/components/scrollto/types.ts +15 -0
  370. package/src/components/select/combobox.ts +305 -0
  371. package/src/components/select/config.ts +324 -0
  372. package/src/components/select/dropdown.ts +510 -0
  373. package/src/components/select/index.ts +13 -0
  374. package/src/components/select/option.ts +43 -0
  375. package/src/components/select/remote.ts +477 -0
  376. package/src/components/select/search.ts +430 -0
  377. package/src/components/select/select.css +105 -0
  378. package/src/components/select/select.ts +1916 -0
  379. package/src/components/select/tags.ts +123 -0
  380. package/src/components/select/templates.ts +531 -0
  381. package/src/components/select/types.ts +36 -0
  382. package/src/components/select/utils.ts +747 -0
  383. package/src/components/select/variants.css +5 -0
  384. package/src/components/separator/separator.css +14 -0
  385. package/src/components/skeleton/skeleton.css +10 -0
  386. package/src/components/stepper/index.ts +7 -0
  387. package/src/components/stepper/stepper.css +49 -0
  388. package/src/components/stepper/stepper.ts +308 -0
  389. package/src/components/stepper/types.ts +13 -0
  390. package/src/components/sticky/index.ts +7 -0
  391. package/src/components/sticky/sticky.css +22 -0
  392. package/src/components/sticky/sticky.ts +381 -0
  393. package/src/components/sticky/types.ts +23 -0
  394. package/src/components/switch/switch.css +110 -0
  395. package/src/components/table/table.css +168 -0
  396. package/src/components/tabs/index.ts +7 -0
  397. package/src/components/tabs/tabs.css +40 -0
  398. package/src/components/tabs/tabs.ts +190 -0
  399. package/src/components/tabs/types.ts +13 -0
  400. package/src/components/textarea/textarea.css +35 -0
  401. package/src/components/theme-switch/index.ts +10 -0
  402. package/src/components/theme-switch/theme-switch.css +22 -0
  403. package/src/components/theme-switch/theme-switch.ts +176 -0
  404. package/src/components/theme-switch/types.ts +15 -0
  405. package/src/components/toggle/index.ts +7 -0
  406. package/src/components/toggle/toggle.css +13 -0
  407. package/src/components/toggle/toggle.ts +173 -0
  408. package/src/components/toggle/types.ts +18 -0
  409. package/src/components/toggle-group/toggle-group.css +55 -0
  410. package/src/components/toggle-password/index.ts +10 -0
  411. package/src/components/toggle-password/toggle-password.css +13 -0
  412. package/src/components/toggle-password/toggle-password.ts +159 -0
  413. package/src/components/toggle-password/types.ts +13 -0
  414. package/src/components/tooltip/index.ts +7 -0
  415. package/src/components/tooltip/tooltip.css +18 -0
  416. package/src/components/tooltip/tooltip.ts +361 -0
  417. package/src/components/tooltip/types.ts +28 -0
  418. package/src/helpers/data.ts +46 -0
  419. package/src/helpers/dom.ts +405 -0
  420. package/src/helpers/event-handler.ts +61 -0
  421. package/src/helpers/utils.ts +183 -0
  422. package/src/index.ts +113 -0
  423. package/src/types.ts +23 -0
  424. package/styles.css +48 -0
  425. package/tsconfig.json +17 -0
  426. package/webpack.config.js +113 -0
@@ -0,0 +1,757 @@
1
+ /**
2
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
3
+ * Copyright 2025 by Keenthemes Inc
4
+ * @version: 1.0.0
5
+ */
6
+ import {
7
+ Instance as PopperInstance,
8
+ createPopper,
9
+ Placement,
10
+ } from '@popperjs/core';
11
+ import KTDom from '../../helpers/dom';
12
+ import KTData from '../../helpers/data';
13
+ import KTComponent from '../component';
14
+ import { KTDatepickerConfigInterface } from './types';
15
+ import { KTDatepickerStateManager } from './config';
16
+ import { KTDatepickerEvents } from './types';
17
+
18
+ /**
19
+ * Class to manage focus within the dropdown
20
+ */
21
+ class FocusManager {
22
+ private _element: HTMLElement;
23
+ private _focusableSelector: string =
24
+ 'button:not([disabled]), [tabindex]:not([tabindex="-1"])';
25
+
26
+ constructor(element: HTMLElement) {
27
+ this._element = element;
28
+ }
29
+
30
+ /**
31
+ * Get all visible focusable options
32
+ */
33
+ public getVisibleOptions(): HTMLElement[] {
34
+ return Array.from(
35
+ this._element.querySelectorAll(this._focusableSelector),
36
+ ).filter((el) => {
37
+ const element = el as HTMLElement;
38
+ return element.offsetParent !== null; // Only visible elements
39
+ }) as HTMLElement[];
40
+ }
41
+
42
+ /**
43
+ * Apply focus to an element
44
+ */
45
+ public applyFocus(element: HTMLElement): void {
46
+ if (element && typeof element.focus === 'function') {
47
+ element.focus();
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Focus next element
53
+ */
54
+ public focusNext(): void {
55
+ const options = this.getVisibleOptions();
56
+ const currentFocused = document.activeElement;
57
+
58
+ let nextIndex = 0;
59
+ if (currentFocused) {
60
+ const currentIndex = options.indexOf(currentFocused as HTMLElement);
61
+ nextIndex = currentIndex >= 0 ? (currentIndex + 1) % options.length : 0;
62
+ }
63
+
64
+ if (options.length > 0) {
65
+ this.applyFocus(options[nextIndex]);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Focus previous element
71
+ */
72
+ public focusPrevious(): void {
73
+ const options = this.getVisibleOptions();
74
+ const currentFocused = document.activeElement;
75
+
76
+ let prevIndex = options.length - 1;
77
+ if (currentFocused) {
78
+ const currentIndex = options.indexOf(currentFocused as HTMLElement);
79
+ prevIndex =
80
+ currentIndex >= 0
81
+ ? (currentIndex - 1 + options.length) % options.length
82
+ : prevIndex;
83
+ }
84
+
85
+ if (options.length > 0) {
86
+ this.applyFocus(options[prevIndex]);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Scroll element into view
92
+ */
93
+ public scrollIntoView(element: HTMLElement): void {
94
+ if (element && typeof element.scrollIntoView === 'function') {
95
+ element.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Clean up resources
101
+ */
102
+ public dispose(): void {
103
+ // Nothing to clean up yet
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Class to manage event listeners
109
+ */
110
+ class EventManager {
111
+ private _listeners: Map<HTMLElement, Map<string, Function[]>> = new Map();
112
+
113
+ /**
114
+ * Add event listener and track it
115
+ */
116
+ public addListener(
117
+ element: HTMLElement,
118
+ eventType: string,
119
+ handler: Function,
120
+ ): void {
121
+ if (!this._listeners.has(element)) {
122
+ this._listeners.set(element, new Map());
123
+ }
124
+
125
+ const elementListeners = this._listeners.get(element)!;
126
+ if (!elementListeners.has(eventType)) {
127
+ elementListeners.set(eventType, []);
128
+ }
129
+
130
+ const handlers = elementListeners.get(eventType)!;
131
+ element.addEventListener(eventType, handler as EventListener);
132
+ handlers.push(handler);
133
+ }
134
+
135
+ /**
136
+ * Remove all listeners for an element
137
+ */
138
+ public removeAllListeners(element: HTMLElement): void {
139
+ if (this._listeners.has(element)) {
140
+ const elementListeners = this._listeners.get(element)!;
141
+
142
+ elementListeners.forEach((handlers, eventType) => {
143
+ handlers.forEach((handler) => {
144
+ element.removeEventListener(eventType, handler as EventListener);
145
+ });
146
+ });
147
+
148
+ this._listeners.delete(element);
149
+ }
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Focus trap class to manage keyboard focus within the dropdown
155
+ */
156
+ class FocusTrap {
157
+ private _element: HTMLElement;
158
+ private _focusableElements: HTMLElement[] = [];
159
+ private _firstFocusableElement: HTMLElement | null = null;
160
+ private _lastFocusableElement: HTMLElement | null = null;
161
+
162
+ /**
163
+ * Constructor
164
+ *
165
+ * @param element - Element to trap focus within
166
+ */
167
+ constructor(element: HTMLElement) {
168
+ this._element = element;
169
+ this._update();
170
+ }
171
+
172
+ /**
173
+ * Update the focusable elements
174
+ */
175
+ public update(): void {
176
+ this._update();
177
+ }
178
+
179
+ /**
180
+ * Update the list of focusable elements
181
+ */
182
+ private _update(): void {
183
+ // Get all focusable elements
184
+ const focusableElements = this._element.querySelectorAll(
185
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
186
+ );
187
+
188
+ // Convert to array and filter out disabled elements
189
+ this._focusableElements = Array.from(focusableElements).filter(
190
+ (el) => !el.hasAttribute('disabled'),
191
+ ) as HTMLElement[];
192
+
193
+ // Get first and last focusable elements
194
+ this._firstFocusableElement = this._focusableElements[0] || null;
195
+ this._lastFocusableElement =
196
+ this._focusableElements[this._focusableElements.length - 1] || null;
197
+ }
198
+
199
+ /**
200
+ * Handle tab key press to trap focus
201
+ *
202
+ * @param event - Keyboard event
203
+ */
204
+ public handleTab(event: KeyboardEvent): void {
205
+ // If no focusable elements, do nothing
206
+ if (!this._firstFocusableElement || !this._lastFocusableElement) {
207
+ event.preventDefault();
208
+ return;
209
+ }
210
+
211
+ const isTabPressed = event.key === 'Tab' || event.keyCode === 9;
212
+
213
+ if (!isTabPressed) return;
214
+
215
+ // Handle Shift+Tab to focus last element when on first
216
+ if (event.shiftKey) {
217
+ if (document.activeElement === this._firstFocusableElement) {
218
+ this._lastFocusableElement.focus();
219
+ event.preventDefault();
220
+ }
221
+ } else {
222
+ // Handle Tab to focus first element when on last
223
+ if (document.activeElement === this._lastFocusableElement) {
224
+ this._firstFocusableElement.focus();
225
+ event.preventDefault();
226
+ }
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Focus the first interactive element
232
+ */
233
+ public focusFirstElement(): void {
234
+ if (this._firstFocusableElement) {
235
+ this._firstFocusableElement.focus();
236
+ }
237
+ }
238
+ }
239
+
240
+ /**
241
+ * KTDatepickerDropdown
242
+ *
243
+ * A specialized dropdown implementation for the KTDatepicker component.
244
+ * This module handles the dropdown functionality for the datepicker component,
245
+ * including positioning, showing/hiding, and keyboard navigation.
246
+ */
247
+ export class KTDatepickerDropdown extends KTComponent {
248
+ protected override readonly _name: string = 'datepicker-dropdown';
249
+ protected override readonly _config: KTDatepickerConfigInterface;
250
+
251
+ // DOM Elements
252
+ protected _element: HTMLElement;
253
+ private _toggleElement: HTMLElement;
254
+ private _dropdownElement: HTMLElement;
255
+
256
+ // State
257
+ private _isOpen: boolean = false;
258
+ private _isTransitioning: boolean = false;
259
+ private _popperInstance: PopperInstance | null = null;
260
+ private _eventManager: EventManager;
261
+ private _focusManager: FocusManager;
262
+ private _focusTrap: FocusTrap | null = null;
263
+ private _activeElement: Element | null = null;
264
+
265
+ /**
266
+ * Constructor
267
+ * @param element The parent element (datepicker wrapper)
268
+ * @param toggleElement The element that triggers the dropdown
269
+ * @param dropdownElement The dropdown content element
270
+ * @param config The configuration options
271
+ */
272
+ constructor(
273
+ element: HTMLElement,
274
+ toggleElement: HTMLElement,
275
+ dropdownElement: HTMLElement,
276
+ config: KTDatepickerConfigInterface,
277
+ ) {
278
+ super();
279
+
280
+ this._element = element;
281
+ this._toggleElement = toggleElement;
282
+ this._dropdownElement = dropdownElement;
283
+ this._config = config;
284
+ this._eventManager = new EventManager();
285
+ this._focusManager = new FocusManager(dropdownElement);
286
+
287
+ this._setupEventListeners();
288
+ }
289
+
290
+ /**
291
+ * Set up event listeners for the dropdown
292
+ */
293
+ private _setupEventListeners(): void {
294
+ // Toggle click
295
+ this._eventManager.addListener(
296
+ this._toggleElement,
297
+ 'click',
298
+ this._handleToggleClick.bind(this),
299
+ );
300
+
301
+ // Keyboard navigation
302
+ this._eventManager.addListener(
303
+ this._element,
304
+ 'keydown',
305
+ this._handleKeyDown.bind(this),
306
+ );
307
+
308
+ // Close on outside click
309
+ this._eventManager.addListener(
310
+ document as unknown as HTMLElement,
311
+ 'click',
312
+ this._handleOutsideClick.bind(this),
313
+ );
314
+ }
315
+
316
+ /**
317
+ * Handle toggle element click
318
+ */
319
+ private _handleToggleClick(event: Event): void {
320
+ event.preventDefault();
321
+ event.stopPropagation();
322
+
323
+ this.toggle();
324
+ }
325
+
326
+ /**
327
+ * Handle keyboard events
328
+ */
329
+ private _handleKeyDown(event: KeyboardEvent): void {
330
+ if (!this._isOpen) return;
331
+
332
+ switch (event.key) {
333
+ case 'Escape':
334
+ event.preventDefault();
335
+ this.close();
336
+ this._toggleElement.focus();
337
+ break;
338
+ case 'ArrowDown':
339
+ event.preventDefault();
340
+ this._focusManager.focusNext();
341
+ break;
342
+ case 'ArrowUp':
343
+ event.preventDefault();
344
+ this._focusManager.focusPrevious();
345
+ break;
346
+ case 'Home':
347
+ event.preventDefault();
348
+ // Focus first visible option
349
+ const firstOption = this._focusManager.getVisibleOptions()[0];
350
+ if (firstOption) {
351
+ this._focusManager.applyFocus(firstOption);
352
+ this._focusManager.scrollIntoView(firstOption);
353
+ }
354
+ break;
355
+ case 'End':
356
+ event.preventDefault();
357
+ // Focus last visible option
358
+ const visibleOptions = this._focusManager.getVisibleOptions();
359
+ const lastOption = visibleOptions[visibleOptions.length - 1];
360
+ if (lastOption) {
361
+ this._focusManager.applyFocus(lastOption);
362
+ this._focusManager.scrollIntoView(lastOption);
363
+ }
364
+ break;
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Handle clicks outside the dropdown
370
+ */
371
+ private _handleOutsideClick(event: MouseEvent): void {
372
+ if (!this._isOpen) return;
373
+
374
+ const target = event.target as HTMLElement;
375
+
376
+ if (
377
+ !this._element.contains(target) &&
378
+ !this._dropdownElement.contains(target)
379
+ ) {
380
+ // Before closing, check if a range selection is in progress
381
+ const datepickerElement = this._element.closest('[data-kt-datepicker]');
382
+ if (datepickerElement) {
383
+ // Get the state manager through the calendar instance or directly
384
+ const stateManager = (datepickerElement as any).instance?._state;
385
+
386
+ if (stateManager) {
387
+ const state = stateManager.getState();
388
+ const config = stateManager.getConfig();
389
+
390
+ // If we're in range mode and range selection is in progress, don't close
391
+ if (config.range && state.isRangeSelectionInProgress) {
392
+ console.log(
393
+ 'Outside click detected but range selection in progress - keeping dropdown open',
394
+ );
395
+ return;
396
+ }
397
+ }
398
+ }
399
+
400
+ this.close();
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Set width of dropdown based on toggle element
406
+ */
407
+ private _setDropdownWidth(): void {
408
+ if (!this._dropdownElement || !this._toggleElement) return;
409
+
410
+ // Get the datepicker configuration
411
+ const datepickerElement = this._element.closest('[data-kt-datepicker]');
412
+ let visibleMonths = 1;
413
+
414
+ if (datepickerElement) {
415
+ // Get visible months from config
416
+ const instance = (datepickerElement as any).instance;
417
+ if (instance && instance._config) {
418
+ visibleMonths = instance._config.visibleMonths || 1;
419
+ }
420
+ }
421
+
422
+ // Calculate appropriate width based on number of visible months
423
+ if (visibleMonths > 1) {
424
+ // For multiple months, calculate a fixed width per month plus padding and gaps
425
+ const monthWidth = 280; // Fixed width for each month
426
+ const padding = 24; // Left/right padding (p-3 = 0.75rem × 2 × 16px = 24px)
427
+ const spacing = 16 * (visibleMonths - 1); // Gap between months (gap-4 = 1rem × 16px)
428
+
429
+ // Limit to showing max 3 months at once for UX (user can scroll to see more)
430
+ const visibleWidth = Math.min(visibleMonths, 3);
431
+
432
+ const totalWidth = monthWidth * visibleWidth + spacing + padding;
433
+
434
+ // Set fixed width for the dropdown
435
+ this._dropdownElement.style.width = `${totalWidth}px`;
436
+ this._dropdownElement.style.minWidth = `${totalWidth}px`;
437
+ } else {
438
+ // For single month, use a fixed width that works well for most calendars
439
+ this._dropdownElement.style.width = '332px'; // 280px calendar width + 24px padding + border
440
+ this._dropdownElement.style.minWidth = '332px';
441
+ }
442
+ }
443
+
444
+ /**
445
+ * Initialize the Popper instance for dropdown positioning
446
+ */
447
+ private _initPopper(): void {
448
+ // Destroy existing popper instance if it exists
449
+ this._destroyPopper();
450
+
451
+ // Default offset
452
+ const offsetValue = '0, 5';
453
+
454
+ // Get configuration options
455
+ const placement = 'bottom-start';
456
+ const strategy = 'absolute';
457
+ const preventOverflow = true;
458
+ const flip = true;
459
+
460
+ // Create new popper instance
461
+ this._popperInstance = createPopper(
462
+ this._toggleElement,
463
+ this._dropdownElement,
464
+ {
465
+ placement: placement as Placement,
466
+ strategy: strategy as 'fixed' | 'absolute',
467
+ modifiers: [
468
+ {
469
+ name: 'offset',
470
+ options: {
471
+ offset: this._parseOffset(offsetValue),
472
+ },
473
+ },
474
+ {
475
+ name: 'preventOverflow',
476
+ options: {
477
+ boundary: 'viewport',
478
+ altAxis: preventOverflow,
479
+ },
480
+ },
481
+ {
482
+ name: 'flip',
483
+ options: {
484
+ enabled: flip,
485
+ fallbackPlacements: ['top-start', 'bottom-end', 'top-end'],
486
+ },
487
+ },
488
+ ],
489
+ },
490
+ );
491
+ }
492
+
493
+ /**
494
+ * Parse offset string into an array of numbers
495
+ */
496
+ private _parseOffset(offset: string): number[] {
497
+ return offset.split(',').map((value) => parseInt(value.trim(), 10));
498
+ }
499
+
500
+ /**
501
+ * Destroy the Popper instance
502
+ */
503
+ private _destroyPopper(): void {
504
+ if (this._popperInstance) {
505
+ this._popperInstance.destroy();
506
+ this._popperInstance = null;
507
+ }
508
+ }
509
+
510
+ /**
511
+ * Update dropdown position
512
+ */
513
+ public updatePosition(): void {
514
+ // Look for the display element rather than using the input directly
515
+ const displayElement = this._element.querySelector(
516
+ '[data-kt-datepicker-display]',
517
+ ) as HTMLElement;
518
+ const triggerElement = displayElement || this._toggleElement;
519
+
520
+ if (!triggerElement || !this._dropdownElement) return;
521
+
522
+ // Reset position styles
523
+ this._dropdownElement.style.top = '';
524
+ this._dropdownElement.style.bottom = '';
525
+ this._dropdownElement.style.left = '';
526
+ this._dropdownElement.style.right = '';
527
+
528
+ // Set width before positioning
529
+ this._setDropdownWidth();
530
+
531
+ // Get position information
532
+ const triggerRect = triggerElement.getBoundingClientRect();
533
+ const containerRect = this._element.getBoundingClientRect();
534
+ const dropdownRect = this._dropdownElement.getBoundingClientRect();
535
+ const viewportHeight = window.innerHeight;
536
+ const viewportWidth = window.innerWidth;
537
+
538
+ // Calculate available space below and above the trigger
539
+ const spaceBelow = viewportHeight - triggerRect.bottom;
540
+ const spaceAbove = triggerRect.top;
541
+
542
+ // Calculate if dropdown would overflow horizontally
543
+ const overflowRight = triggerRect.left + dropdownRect.width > viewportWidth;
544
+
545
+ // Position dropdown
546
+ this._dropdownElement.style.position = 'absolute';
547
+
548
+ // Determine vertical position
549
+ if (spaceBelow >= dropdownRect.height || spaceBelow >= spaceAbove) {
550
+ // Position below the trigger
551
+ this._dropdownElement.style.top = `${triggerRect.height + 5}px`;
552
+ } else {
553
+ // Position above the trigger
554
+ this._dropdownElement.style.bottom = `${triggerRect.height + 5}px`;
555
+ }
556
+
557
+ // Determine horizontal position - handle potential overflow
558
+ if (overflowRight) {
559
+ // Align with right edge of trigger to prevent overflow
560
+ const rightOffset = Math.max(0, dropdownRect.width - triggerRect.width);
561
+ this._dropdownElement.style.right = `0px`;
562
+ } else {
563
+ // Align with left edge of trigger
564
+ this._dropdownElement.style.left = `0px`;
565
+ }
566
+ }
567
+
568
+ /**
569
+ * Toggle the dropdown
570
+ */
571
+ public toggle(): void {
572
+ if (this._isOpen) {
573
+ this.close();
574
+ } else {
575
+ this.open();
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Open the dropdown
581
+ */
582
+ public open(): void {
583
+ if (this._isOpen || this._isTransitioning) return;
584
+
585
+ // Fire before show event
586
+ const beforeShowEvent = new CustomEvent('kt.datepicker.dropdown.show', {
587
+ bubbles: true,
588
+ cancelable: true,
589
+ });
590
+ this._element.dispatchEvent(beforeShowEvent);
591
+
592
+ if (beforeShowEvent.defaultPrevented) return;
593
+
594
+ // Begin opening transition
595
+ this._isTransitioning = true;
596
+
597
+ // Set dropdown visibility
598
+ this._dropdownElement.classList.remove('hidden');
599
+ this._dropdownElement.setAttribute('aria-hidden', 'false');
600
+
601
+ // Set dropdown width
602
+ this._setDropdownWidth();
603
+
604
+ // Make sure the element is visible for transitioning
605
+ KTDom.reflow(this._dropdownElement);
606
+
607
+ // Apply z-index
608
+ this._dropdownElement.style.zIndex = '1000';
609
+
610
+ // Initialize popper for positioning
611
+ this._initPopper();
612
+
613
+ // Add active classes
614
+ this._toggleElement.classList.add('ring', 'ring-blue-300');
615
+ this._toggleElement.setAttribute('aria-expanded', 'true');
616
+
617
+ // Start transition
618
+ this._dropdownElement.classList.remove('opacity-0', 'translate-y-2');
619
+ this._dropdownElement.classList.add('opacity-100', 'translate-y-0');
620
+
621
+ // Handle transition end
622
+ KTDom.transitionEnd(this._dropdownElement, () => {
623
+ this._isTransitioning = false;
624
+ this._isOpen = true;
625
+
626
+ // Focus the first interactive element
627
+ this._focusFirstInteractiveElement();
628
+
629
+ // Fire after show event
630
+ const afterShowEvent = new CustomEvent('kt.datepicker.dropdown.shown', {
631
+ bubbles: true,
632
+ });
633
+ this._element.dispatchEvent(afterShowEvent);
634
+ });
635
+ }
636
+
637
+ /**
638
+ * Focus the first interactive element in the dropdown
639
+ */
640
+ private _focusFirstInteractiveElement(): void {
641
+ // Priority of elements to focus:
642
+ // 1. A "Today" button if available
643
+ // 2. The first day in the current month
644
+ // 3. Any other focusable element
645
+
646
+ // Find the Today button using standard DOM selectors
647
+ let todayBtn: HTMLElement | null = null;
648
+ const buttons = this._dropdownElement.querySelectorAll('button');
649
+ for (let i = 0; i < buttons.length; i++) {
650
+ if (buttons[i].textContent && buttons[i].textContent.trim() === 'Today') {
651
+ todayBtn = buttons[i] as HTMLElement;
652
+ break;
653
+ }
654
+ }
655
+
656
+ if (todayBtn) {
657
+ todayBtn.focus();
658
+ return;
659
+ }
660
+
661
+ const currentMonthDay = this._dropdownElement.querySelector(
662
+ 'button[data-date]:not(.text-gray-400)',
663
+ ) as HTMLElement;
664
+ if (currentMonthDay) {
665
+ currentMonthDay.focus();
666
+ return;
667
+ }
668
+
669
+ const firstOption = this._focusManager.getVisibleOptions()[0];
670
+ if (firstOption) {
671
+ this._focusManager.applyFocus(firstOption);
672
+ }
673
+ }
674
+
675
+ /**
676
+ * Close the dropdown
677
+ */
678
+ public close(): void {
679
+ if (!this._isOpen || this._isTransitioning) return;
680
+
681
+ // Fire before hide event
682
+ const beforeHideEvent = new CustomEvent('kt.datepicker.dropdown.hide', {
683
+ bubbles: true,
684
+ cancelable: true,
685
+ });
686
+ this._element.dispatchEvent(beforeHideEvent);
687
+
688
+ if (beforeHideEvent.defaultPrevented) return;
689
+
690
+ // Begin closing transition
691
+ this._isTransitioning = true;
692
+
693
+ // Start transition
694
+ this._dropdownElement.classList.add('opacity-0', 'translate-y-2');
695
+ this._dropdownElement.classList.remove('opacity-100', 'translate-y-0');
696
+
697
+ // Handle transition end
698
+ KTDom.transitionEnd(this._dropdownElement, () => {
699
+ // Remove active classes
700
+ this._dropdownElement.classList.add('hidden');
701
+ this._dropdownElement.setAttribute('aria-hidden', 'true');
702
+
703
+ // Reset styles
704
+ this._dropdownElement.style.opacity = '';
705
+ this._dropdownElement.style.transform = '';
706
+ this._dropdownElement.style.zIndex = '';
707
+
708
+ // Destroy popper
709
+ this._destroyPopper();
710
+
711
+ // Update state
712
+ this._isTransitioning = false;
713
+ this._isOpen = false;
714
+
715
+ // Fire after hide event
716
+ const afterHideEvent = new CustomEvent('kt.datepicker.dropdown.hidden', {
717
+ bubbles: true,
718
+ });
719
+ this._element.dispatchEvent(afterHideEvent);
720
+ });
721
+ }
722
+
723
+ /**
724
+ * Check if dropdown is open
725
+ */
726
+ public isOpen(): boolean {
727
+ return this._isOpen;
728
+ }
729
+
730
+ /**
731
+ * Clean up component
732
+ */
733
+ public override dispose(): void {
734
+ // Destroy popper
735
+ this._destroyPopper();
736
+
737
+ // Remove event listeners
738
+ this._eventManager.removeAllListeners(this._element);
739
+ this._eventManager.removeAllListeners(this._toggleElement);
740
+ this._eventManager.removeAllListeners(document as unknown as HTMLElement);
741
+
742
+ // Clean up focus manager
743
+ if (
744
+ this._focusManager &&
745
+ typeof this._focusManager.dispose === 'function'
746
+ ) {
747
+ this._focusManager.dispose();
748
+ }
749
+
750
+ // Clean up state
751
+ this._isOpen = false;
752
+ this._isTransitioning = false;
753
+
754
+ // Remove data reference
755
+ KTData.remove(this._element, this._name);
756
+ }
757
+ }