@keenthemes/ktui 1.2.0 → 1.2.2

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 (348) hide show
  1. package/dist/ktui.js +8355 -5213
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/dist/styles.css +24 -1
  5. package/lib/cjs/components/carousel/carousel.d.ts +102 -0
  6. package/lib/cjs/components/carousel/carousel.d.ts.map +1 -0
  7. package/lib/cjs/components/carousel/carousel.js +769 -0
  8. package/lib/cjs/components/carousel/carousel.js.map +1 -0
  9. package/lib/cjs/components/carousel/index.d.ts +7 -0
  10. package/lib/cjs/components/carousel/index.d.ts.map +1 -0
  11. package/lib/cjs/components/carousel/index.js +10 -0
  12. package/lib/cjs/components/carousel/index.js.map +1 -0
  13. package/lib/cjs/components/carousel/types.d.ts +36 -0
  14. package/lib/cjs/components/carousel/types.d.ts.map +1 -0
  15. package/lib/cjs/components/carousel/types.js +7 -0
  16. package/lib/cjs/components/carousel/types.js.map +1 -0
  17. package/lib/cjs/components/clipboard/clipboard.d.ts +37 -0
  18. package/lib/cjs/components/clipboard/clipboard.d.ts.map +1 -0
  19. package/lib/cjs/components/clipboard/clipboard.js +402 -0
  20. package/lib/cjs/components/clipboard/clipboard.js.map +1 -0
  21. package/lib/cjs/components/clipboard/index.d.ts +3 -0
  22. package/lib/cjs/components/clipboard/index.d.ts.map +1 -0
  23. package/lib/cjs/components/clipboard/index.js +6 -0
  24. package/lib/cjs/components/clipboard/index.js.map +1 -0
  25. package/lib/cjs/components/clipboard/types.d.ts +44 -0
  26. package/lib/cjs/components/clipboard/types.d.ts.map +1 -0
  27. package/lib/cjs/components/clipboard/types.js +7 -0
  28. package/lib/cjs/components/clipboard/types.js.map +1 -0
  29. package/lib/cjs/components/component.d.ts +3 -3
  30. package/lib/cjs/components/component.d.ts.map +1 -1
  31. package/lib/cjs/components/component.js +9 -1
  32. package/lib/cjs/components/component.js.map +1 -1
  33. package/lib/cjs/components/datatable/datatable-checkbox.d.ts +1 -1
  34. package/lib/cjs/components/datatable/datatable-checkbox.d.ts.map +1 -1
  35. package/lib/cjs/components/datatable/datatable-checkbox.js +1 -1
  36. package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
  37. package/lib/cjs/components/datatable/datatable-sort.d.ts +1 -1
  38. package/lib/cjs/components/datatable/datatable-sort.d.ts.map +1 -1
  39. package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
  40. package/lib/cjs/components/datatable/datatable.d.ts +2 -0
  41. package/lib/cjs/components/datatable/datatable.d.ts.map +1 -1
  42. package/lib/cjs/components/datatable/datatable.js +29 -16
  43. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  44. package/lib/cjs/components/datatable/types.d.ts +2 -1
  45. package/lib/cjs/components/datatable/types.d.ts.map +1 -1
  46. package/lib/cjs/components/drawer/drawer.d.ts.map +1 -1
  47. package/lib/cjs/components/drawer/drawer.js +3 -16
  48. package/lib/cjs/components/drawer/drawer.js.map +1 -1
  49. package/lib/cjs/components/dropdown/dropdown.d.ts +1 -1
  50. package/lib/cjs/components/dropdown/dropdown.d.ts.map +1 -1
  51. package/lib/cjs/components/dropdown/dropdown.js +2 -3
  52. package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
  53. package/lib/cjs/components/pin-input/index.d.ts +3 -0
  54. package/lib/cjs/components/pin-input/index.d.ts.map +1 -0
  55. package/lib/cjs/components/pin-input/index.js +6 -0
  56. package/lib/cjs/components/pin-input/index.js.map +1 -0
  57. package/lib/cjs/components/pin-input/pin-input.d.ts +56 -0
  58. package/lib/cjs/components/pin-input/pin-input.d.ts.map +1 -0
  59. package/lib/cjs/components/pin-input/pin-input.js +455 -0
  60. package/lib/cjs/components/pin-input/pin-input.js.map +1 -0
  61. package/lib/cjs/components/pin-input/types.d.ts +41 -0
  62. package/lib/cjs/components/pin-input/types.d.ts.map +1 -0
  63. package/lib/cjs/components/pin-input/types.js +6 -0
  64. package/lib/cjs/components/pin-input/types.js.map +1 -0
  65. package/lib/cjs/components/range-slider/index.d.ts +7 -0
  66. package/lib/cjs/components/range-slider/index.d.ts.map +1 -0
  67. package/lib/cjs/components/range-slider/index.js +10 -0
  68. package/lib/cjs/components/range-slider/index.js.map +1 -0
  69. package/lib/cjs/components/range-slider/range-slider.d.ts +42 -0
  70. package/lib/cjs/components/range-slider/range-slider.d.ts.map +1 -0
  71. package/lib/cjs/components/range-slider/range-slider.js +254 -0
  72. package/lib/cjs/components/range-slider/range-slider.js.map +1 -0
  73. package/lib/cjs/components/range-slider/types.d.ts +33 -0
  74. package/lib/cjs/components/range-slider/types.d.ts.map +1 -0
  75. package/lib/cjs/components/range-slider/types.js +7 -0
  76. package/lib/cjs/components/range-slider/types.js.map +1 -0
  77. package/lib/cjs/components/rating/rating.d.ts.map +1 -1
  78. package/lib/cjs/components/rating/rating.js +8 -3
  79. package/lib/cjs/components/rating/rating.js.map +1 -1
  80. package/lib/cjs/components/repeater/repeater.d.ts.map +1 -1
  81. package/lib/cjs/components/repeater/repeater.js +3 -2
  82. package/lib/cjs/components/repeater/repeater.js.map +1 -1
  83. package/lib/cjs/components/select/combobox.d.ts.map +1 -1
  84. package/lib/cjs/components/select/combobox.js +25 -15
  85. package/lib/cjs/components/select/combobox.js.map +1 -1
  86. package/lib/cjs/components/select/config.d.ts +2 -2
  87. package/lib/cjs/components/select/config.d.ts.map +1 -1
  88. package/lib/cjs/components/select/config.js +10 -9
  89. package/lib/cjs/components/select/config.js.map +1 -1
  90. package/lib/cjs/components/select/dropdown.js.map +1 -1
  91. package/lib/cjs/components/select/option.d.ts +2 -1
  92. package/lib/cjs/components/select/option.d.ts.map +1 -1
  93. package/lib/cjs/components/select/option.js +9 -3
  94. package/lib/cjs/components/select/option.js.map +1 -1
  95. package/lib/cjs/components/select/remote.d.ts +1 -0
  96. package/lib/cjs/components/select/remote.d.ts.map +1 -1
  97. package/lib/cjs/components/select/remote.js +21 -14
  98. package/lib/cjs/components/select/remote.js.map +1 -1
  99. package/lib/cjs/components/select/search.d.ts +1 -1
  100. package/lib/cjs/components/select/search.d.ts.map +1 -1
  101. package/lib/cjs/components/select/search.js +34 -25
  102. package/lib/cjs/components/select/search.js.map +1 -1
  103. package/lib/cjs/components/select/select.d.ts +5 -3
  104. package/lib/cjs/components/select/select.d.ts.map +1 -1
  105. package/lib/cjs/components/select/select.js +31 -31
  106. package/lib/cjs/components/select/select.js.map +1 -1
  107. package/lib/cjs/components/select/tags.d.ts.map +1 -1
  108. package/lib/cjs/components/select/tags.js +22 -13
  109. package/lib/cjs/components/select/tags.js.map +1 -1
  110. package/lib/cjs/components/select/templates.d.ts.map +1 -1
  111. package/lib/cjs/components/select/templates.js +4 -4
  112. package/lib/cjs/components/select/templates.js.map +1 -1
  113. package/lib/cjs/components/select/types.d.ts +1 -1
  114. package/lib/cjs/components/select/types.d.ts.map +1 -1
  115. package/lib/cjs/components/select/utils.d.ts +4 -4
  116. package/lib/cjs/components/select/utils.d.ts.map +1 -1
  117. package/lib/cjs/components/select/utils.js +5 -4
  118. package/lib/cjs/components/select/utils.js.map +1 -1
  119. package/lib/cjs/components/sticky/sticky.d.ts +1 -1
  120. package/lib/cjs/components/sticky/sticky.d.ts.map +1 -1
  121. package/lib/cjs/components/sticky/sticky.js +16 -14
  122. package/lib/cjs/components/sticky/sticky.js.map +1 -1
  123. package/lib/cjs/components/toast/toast.d.ts.map +1 -1
  124. package/lib/cjs/components/toast/toast.js +17 -9
  125. package/lib/cjs/components/toast/toast.js.map +1 -1
  126. package/lib/cjs/components/toast/types.d.ts +3 -0
  127. package/lib/cjs/components/toast/types.d.ts.map +1 -1
  128. package/lib/cjs/components/toggle-password/toggle-password.d.ts.map +1 -1
  129. package/lib/cjs/components/toggle-password/toggle-password.js.map +1 -1
  130. package/lib/cjs/helpers/dom.d.ts +4 -4
  131. package/lib/cjs/helpers/dom.d.ts.map +1 -1
  132. package/lib/cjs/helpers/dom.js +8 -10
  133. package/lib/cjs/helpers/dom.js.map +1 -1
  134. package/lib/cjs/helpers/event-handler.d.ts +1 -1
  135. package/lib/cjs/helpers/event-handler.d.ts.map +1 -1
  136. package/lib/cjs/helpers/event-handler.js +3 -1
  137. package/lib/cjs/helpers/event-handler.js.map +1 -1
  138. package/lib/cjs/helpers/utils.d.ts +1 -1
  139. package/lib/cjs/helpers/utils.d.ts.map +1 -1
  140. package/lib/cjs/helpers/utils.js +4 -1
  141. package/lib/cjs/helpers/utils.js.map +1 -1
  142. package/lib/cjs/index.d.ts +16 -0
  143. package/lib/cjs/index.d.ts.map +1 -1
  144. package/lib/cjs/index.js +17 -1
  145. package/lib/cjs/index.js.map +1 -1
  146. package/lib/cjs/types.d.ts +1 -1
  147. package/lib/cjs/types.d.ts.map +1 -1
  148. package/lib/esm/components/carousel/carousel.d.ts +102 -0
  149. package/lib/esm/components/carousel/carousel.d.ts.map +1 -0
  150. package/lib/esm/components/carousel/carousel.js +766 -0
  151. package/lib/esm/components/carousel/carousel.js.map +1 -0
  152. package/lib/esm/components/carousel/index.d.ts +7 -0
  153. package/lib/esm/components/carousel/index.d.ts.map +1 -0
  154. package/lib/esm/components/carousel/index.js +6 -0
  155. package/lib/esm/components/carousel/index.js.map +1 -0
  156. package/lib/esm/components/carousel/types.d.ts +36 -0
  157. package/lib/esm/components/carousel/types.d.ts.map +1 -0
  158. package/lib/esm/components/carousel/types.js +6 -0
  159. package/lib/esm/components/carousel/types.js.map +1 -0
  160. package/lib/esm/components/clipboard/clipboard.d.ts +37 -0
  161. package/lib/esm/components/clipboard/clipboard.d.ts.map +1 -0
  162. package/lib/esm/components/clipboard/clipboard.js +399 -0
  163. package/lib/esm/components/clipboard/clipboard.js.map +1 -0
  164. package/lib/esm/components/clipboard/index.d.ts +3 -0
  165. package/lib/esm/components/clipboard/index.d.ts.map +1 -0
  166. package/lib/esm/components/clipboard/index.js +2 -0
  167. package/lib/esm/components/clipboard/index.js.map +1 -0
  168. package/lib/esm/components/clipboard/types.d.ts +44 -0
  169. package/lib/esm/components/clipboard/types.d.ts.map +1 -0
  170. package/lib/esm/components/clipboard/types.js +6 -0
  171. package/lib/esm/components/clipboard/types.js.map +1 -0
  172. package/lib/esm/components/component.d.ts +3 -3
  173. package/lib/esm/components/component.d.ts.map +1 -1
  174. package/lib/esm/components/component.js +9 -1
  175. package/lib/esm/components/component.js.map +1 -1
  176. package/lib/esm/components/datatable/datatable-checkbox.d.ts +1 -1
  177. package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -1
  178. package/lib/esm/components/datatable/datatable-checkbox.js +1 -1
  179. package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
  180. package/lib/esm/components/datatable/datatable-sort.d.ts +1 -1
  181. package/lib/esm/components/datatable/datatable-sort.d.ts.map +1 -1
  182. package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
  183. package/lib/esm/components/datatable/datatable.d.ts +2 -0
  184. package/lib/esm/components/datatable/datatable.d.ts.map +1 -1
  185. package/lib/esm/components/datatable/datatable.js +29 -16
  186. package/lib/esm/components/datatable/datatable.js.map +1 -1
  187. package/lib/esm/components/datatable/types.d.ts +2 -1
  188. package/lib/esm/components/datatable/types.d.ts.map +1 -1
  189. package/lib/esm/components/drawer/drawer.d.ts.map +1 -1
  190. package/lib/esm/components/drawer/drawer.js +3 -16
  191. package/lib/esm/components/drawer/drawer.js.map +1 -1
  192. package/lib/esm/components/dropdown/dropdown.d.ts +1 -1
  193. package/lib/esm/components/dropdown/dropdown.d.ts.map +1 -1
  194. package/lib/esm/components/dropdown/dropdown.js +2 -3
  195. package/lib/esm/components/dropdown/dropdown.js.map +1 -1
  196. package/lib/esm/components/pin-input/index.d.ts +3 -0
  197. package/lib/esm/components/pin-input/index.d.ts.map +1 -0
  198. package/lib/esm/components/pin-input/index.js +2 -0
  199. package/lib/esm/components/pin-input/index.js.map +1 -0
  200. package/lib/esm/components/pin-input/pin-input.d.ts +56 -0
  201. package/lib/esm/components/pin-input/pin-input.d.ts.map +1 -0
  202. package/lib/esm/components/pin-input/pin-input.js +452 -0
  203. package/lib/esm/components/pin-input/pin-input.js.map +1 -0
  204. package/lib/esm/components/pin-input/types.d.ts +41 -0
  205. package/lib/esm/components/pin-input/types.d.ts.map +1 -0
  206. package/lib/esm/components/pin-input/types.js +5 -0
  207. package/lib/esm/components/pin-input/types.js.map +1 -0
  208. package/lib/esm/components/range-slider/index.d.ts +7 -0
  209. package/lib/esm/components/range-slider/index.d.ts.map +1 -0
  210. package/lib/esm/components/range-slider/index.js +6 -0
  211. package/lib/esm/components/range-slider/index.js.map +1 -0
  212. package/lib/esm/components/range-slider/range-slider.d.ts +42 -0
  213. package/lib/esm/components/range-slider/range-slider.d.ts.map +1 -0
  214. package/lib/esm/components/range-slider/range-slider.js +251 -0
  215. package/lib/esm/components/range-slider/range-slider.js.map +1 -0
  216. package/lib/esm/components/range-slider/types.d.ts +33 -0
  217. package/lib/esm/components/range-slider/types.d.ts.map +1 -0
  218. package/lib/esm/components/range-slider/types.js +6 -0
  219. package/lib/esm/components/range-slider/types.js.map +1 -0
  220. package/lib/esm/components/rating/rating.d.ts.map +1 -1
  221. package/lib/esm/components/rating/rating.js +8 -3
  222. package/lib/esm/components/rating/rating.js.map +1 -1
  223. package/lib/esm/components/repeater/repeater.d.ts.map +1 -1
  224. package/lib/esm/components/repeater/repeater.js +3 -2
  225. package/lib/esm/components/repeater/repeater.js.map +1 -1
  226. package/lib/esm/components/select/combobox.d.ts.map +1 -1
  227. package/lib/esm/components/select/combobox.js +25 -15
  228. package/lib/esm/components/select/combobox.js.map +1 -1
  229. package/lib/esm/components/select/config.d.ts +2 -2
  230. package/lib/esm/components/select/config.d.ts.map +1 -1
  231. package/lib/esm/components/select/config.js +10 -9
  232. package/lib/esm/components/select/config.js.map +1 -1
  233. package/lib/esm/components/select/dropdown.js.map +1 -1
  234. package/lib/esm/components/select/option.d.ts +2 -1
  235. package/lib/esm/components/select/option.d.ts.map +1 -1
  236. package/lib/esm/components/select/option.js +9 -3
  237. package/lib/esm/components/select/option.js.map +1 -1
  238. package/lib/esm/components/select/remote.d.ts +1 -0
  239. package/lib/esm/components/select/remote.d.ts.map +1 -1
  240. package/lib/esm/components/select/remote.js +21 -14
  241. package/lib/esm/components/select/remote.js.map +1 -1
  242. package/lib/esm/components/select/search.d.ts +1 -1
  243. package/lib/esm/components/select/search.d.ts.map +1 -1
  244. package/lib/esm/components/select/search.js +34 -25
  245. package/lib/esm/components/select/search.js.map +1 -1
  246. package/lib/esm/components/select/select.d.ts +5 -3
  247. package/lib/esm/components/select/select.d.ts.map +1 -1
  248. package/lib/esm/components/select/select.js +31 -31
  249. package/lib/esm/components/select/select.js.map +1 -1
  250. package/lib/esm/components/select/tags.d.ts.map +1 -1
  251. package/lib/esm/components/select/tags.js +22 -13
  252. package/lib/esm/components/select/tags.js.map +1 -1
  253. package/lib/esm/components/select/templates.d.ts.map +1 -1
  254. package/lib/esm/components/select/templates.js +4 -4
  255. package/lib/esm/components/select/templates.js.map +1 -1
  256. package/lib/esm/components/select/types.d.ts +1 -1
  257. package/lib/esm/components/select/types.d.ts.map +1 -1
  258. package/lib/esm/components/select/utils.d.ts +4 -4
  259. package/lib/esm/components/select/utils.d.ts.map +1 -1
  260. package/lib/esm/components/select/utils.js +5 -4
  261. package/lib/esm/components/select/utils.js.map +1 -1
  262. package/lib/esm/components/sticky/sticky.d.ts +1 -1
  263. package/lib/esm/components/sticky/sticky.d.ts.map +1 -1
  264. package/lib/esm/components/sticky/sticky.js +16 -14
  265. package/lib/esm/components/sticky/sticky.js.map +1 -1
  266. package/lib/esm/components/toast/toast.d.ts.map +1 -1
  267. package/lib/esm/components/toast/toast.js +17 -9
  268. package/lib/esm/components/toast/toast.js.map +1 -1
  269. package/lib/esm/components/toast/types.d.ts +3 -0
  270. package/lib/esm/components/toast/types.d.ts.map +1 -1
  271. package/lib/esm/components/toggle-password/toggle-password.d.ts.map +1 -1
  272. package/lib/esm/components/toggle-password/toggle-password.js.map +1 -1
  273. package/lib/esm/helpers/dom.d.ts +4 -4
  274. package/lib/esm/helpers/dom.d.ts.map +1 -1
  275. package/lib/esm/helpers/dom.js +8 -10
  276. package/lib/esm/helpers/dom.js.map +1 -1
  277. package/lib/esm/helpers/event-handler.d.ts +1 -1
  278. package/lib/esm/helpers/event-handler.d.ts.map +1 -1
  279. package/lib/esm/helpers/event-handler.js +3 -1
  280. package/lib/esm/helpers/event-handler.js.map +1 -1
  281. package/lib/esm/helpers/utils.d.ts +1 -1
  282. package/lib/esm/helpers/utils.d.ts.map +1 -1
  283. package/lib/esm/helpers/utils.js +4 -1
  284. package/lib/esm/helpers/utils.js.map +1 -1
  285. package/lib/esm/index.d.ts +16 -0
  286. package/lib/esm/index.d.ts.map +1 -1
  287. package/lib/esm/index.js +12 -0
  288. package/lib/esm/index.js.map +1 -1
  289. package/lib/esm/types.d.ts +1 -1
  290. package/lib/esm/types.d.ts.map +1 -1
  291. package/package.json +5 -3
  292. package/src/components/carousel/__tests__/carousel.test.ts +326 -0
  293. package/src/components/carousel/carousel.css +42 -0
  294. package/src/components/carousel/carousel.ts +847 -0
  295. package/src/components/carousel/index.ts +11 -0
  296. package/src/components/carousel/types.ts +38 -0
  297. package/src/components/clipboard/__tests__/clipboard.test.ts +438 -0
  298. package/src/components/clipboard/clipboard.ts +416 -0
  299. package/src/components/clipboard/index.ts +2 -0
  300. package/src/components/clipboard/types.ts +51 -0
  301. package/src/components/component.ts +15 -5
  302. package/src/components/datatable/__tests__/currency-sort.test.ts +6 -13
  303. package/src/components/datatable/__tests__/multi-row-headers.test.ts +2 -2
  304. package/src/components/datatable/__tests__/pagination-reset.test.ts +7 -4
  305. package/src/components/datatable/__tests__/race-conditions.test.ts +11 -14
  306. package/src/components/datatable/__tests__/setup.ts +1 -1
  307. package/src/components/datatable/datatable-checkbox.ts +6 -4
  308. package/src/components/datatable/datatable-sort.ts +27 -7
  309. package/src/components/datatable/datatable.ts +67 -42
  310. package/src/components/datatable/types.ts +3 -1
  311. package/src/components/drawer/drawer.ts +3 -18
  312. package/src/components/dropdown/dropdown.ts +2 -3
  313. package/src/components/pin-input/__tests__/pin-input.test.ts +928 -0
  314. package/src/components/pin-input/index.ts +6 -0
  315. package/src/components/pin-input/pin-input.ts +499 -0
  316. package/src/components/pin-input/types.ts +45 -0
  317. package/src/components/range-slider/__tests__/range-slider.test.ts +659 -0
  318. package/src/components/range-slider/index.ts +11 -0
  319. package/src/components/range-slider/range-slider.ts +276 -0
  320. package/src/components/range-slider/types.ts +36 -0
  321. package/src/components/rating/__tests__/rating.test.ts +11 -4
  322. package/src/components/rating/rating.ts +22 -12
  323. package/src/components/repeater/__tests__/repeater.test.ts +24 -11
  324. package/src/components/repeater/repeater.ts +5 -3
  325. package/src/components/select/__tests__/ux-behaviors.test.ts +25 -6
  326. package/src/components/select/combobox.ts +23 -16
  327. package/src/components/select/config.ts +15 -14
  328. package/src/components/select/dropdown.ts +1 -1
  329. package/src/components/select/option.ts +14 -4
  330. package/src/components/select/remote.ts +68 -56
  331. package/src/components/select/search.ts +30 -27
  332. package/src/components/select/select.ts +41 -37
  333. package/src/components/select/tags.ts +14 -8
  334. package/src/components/select/templates.ts +11 -6
  335. package/src/components/select/types.ts +1 -1
  336. package/src/components/select/utils.ts +12 -10
  337. package/src/components/sticky/__tests__/sticky.test.ts +10 -3
  338. package/src/components/sticky/sticky.ts +16 -26
  339. package/src/components/sticky/types.ts +3 -3
  340. package/src/components/toast/toast.ts +34 -21
  341. package/src/components/toast/types.ts +5 -1
  342. package/src/components/toggle-password/toggle-password.ts +0 -1
  343. package/src/helpers/dom.ts +14 -17
  344. package/src/helpers/event-handler.ts +5 -6
  345. package/src/helpers/utils.ts +5 -2
  346. package/src/index.ts +35 -0
  347. package/src/types.ts +1 -1
  348. package/styles.css +1 -0
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { KTSelectConfigInterface } from './config';
7
7
  import { KTSelect } from './select';
8
- import { filterOptions, renderTemplateString, stringToElement } from './utils';
8
+ import { filterOptions, FocusManager } from './utils';
9
9
  import { defaultTemplates } from './templates';
10
10
 
11
11
  /**
@@ -14,7 +14,7 @@ import { defaultTemplates } from './templates';
14
14
  export class KTSelectCombobox {
15
15
  private _select: KTSelect;
16
16
  private _config: KTSelectConfigInterface;
17
- private _searchInputElement: HTMLInputElement;
17
+ private _searchInputElement: HTMLInputElement | null;
18
18
  private _clearButtonElement: HTMLElement | null;
19
19
  private _boundInputHandler: (event: Event) => void;
20
20
  private _boundClearHandler: (event: MouseEvent) => void;
@@ -41,16 +41,18 @@ export class KTSelectCombobox {
41
41
 
42
42
  this._attachEventListeners();
43
43
 
44
- this._select.getElement().addEventListener('dropdown.close', () => {
44
+ this._select.getElement()?.addEventListener('dropdown.close', () => {
45
45
  // When dropdown closes, if not multi-select and not using displayTemplate,
46
46
  // ensure input shows the selected value or placeholder.
47
47
  if (!this._config.multiple && !this._config.displayTemplate) {
48
48
  this.updateDisplay(this._select.getSelectedOptions());
49
49
  } else {
50
50
  // For tags or displayTemplate, the input should be clear for typing.
51
- this._searchInputElement.value = '';
51
+ if (this._searchInputElement) {
52
+ this._searchInputElement.value = '';
53
+ }
52
54
  }
53
- this._toggleClearButtonVisibility(this._searchInputElement.value);
55
+ this._toggleClearButtonVisibility(this._searchInputElement?.value ?? '');
54
56
  // this._select.showAllOptions(); // showAllOptions might be too broad, filtering is managed by typing.
55
57
  });
56
58
  }
@@ -102,7 +104,7 @@ export class KTSelectCombobox {
102
104
 
103
105
  this._toggleClearButtonVisibility(query);
104
106
 
105
- if (!(this._select as any).isDropdownOpen()) {
107
+ if (!this._select.isDropdownOpen()) {
106
108
  // Use public getter
107
109
  this._select.openDropdown();
108
110
  }
@@ -125,6 +127,7 @@ export class KTSelectCombobox {
125
127
  private _handleClearButtonClick(event: MouseEvent): void {
126
128
  event.preventDefault();
127
129
  event.stopPropagation();
130
+ if (!this._searchInputElement) return;
128
131
 
129
132
  this._searchInputElement.value = '';
130
133
  this._toggleClearButtonVisibility('');
@@ -134,7 +137,7 @@ export class KTSelectCombobox {
134
137
  this._select.clearSelection(); // This will also trigger updateSelectedOptionDisplay
135
138
  this._select.showAllOptions(); // Show all options after clearing
136
139
  this._select.openDropdown();
137
- this._searchInputElement.focus();
140
+ this._searchInputElement?.focus();
138
141
  }
139
142
 
140
143
  /**
@@ -170,7 +173,10 @@ export class KTSelectCombobox {
170
173
  // or the main FocusManager should adjust focus if needed.
171
174
  // For combobox, this filtering is the primary search mechanism.
172
175
  // We might need to tell select's focus manager to focus first option.
173
- (this._select as any)._focusManager.focusFirst(); // Consider if this is always right
176
+ const focusManager = (
177
+ this._select as unknown as { _focusManager?: FocusManager }
178
+ )._focusManager;
179
+ focusManager?.focusFirst();
174
180
  }
175
181
 
176
182
  /**
@@ -185,17 +191,18 @@ export class KTSelectCombobox {
185
191
  }
186
192
 
187
193
  if (this._config.tags && this._valuesContainerElement) {
194
+ const valuesContainer = this._valuesContainerElement;
195
+ const selectElement = this._select.getElement();
196
+ if (!selectElement) return;
188
197
  // Combobox + Tags
189
198
  selectedOptions.forEach((value) => {
190
199
  // Ensure value is properly escaped for querySelector
191
- const optionElement = this._select
192
- .getElement()
193
- .querySelector(
194
- `option[value="${CSS.escape(value)}"]`,
195
- ) as HTMLOptionElement;
200
+ const optionElement = selectElement.querySelector(
201
+ `option[value="${CSS.escape(value)}"]`,
202
+ ) as HTMLOptionElement;
196
203
  if (optionElement) {
197
204
  const tagElement = defaultTemplates.tag(optionElement, this._config);
198
- this._valuesContainerElement.appendChild(tagElement);
205
+ valuesContainer.appendChild(tagElement);
199
206
  }
200
207
  });
201
208
  this._searchInputElement.value = ''; // Input field is for typing new searches
@@ -219,7 +226,7 @@ export class KTSelectCombobox {
219
226
  .map((value) => {
220
227
  const optionEl = this._select
221
228
  .getElement()
222
- .querySelector(`option[value="${CSS.escape(value)}"]`);
229
+ ?.querySelector(`option[value="${CSS.escape(value)}"]`);
223
230
  return optionEl ? optionEl.textContent : '';
224
231
  })
225
232
  .join(', '); // Basic comma separation
@@ -233,7 +240,7 @@ export class KTSelectCombobox {
233
240
  const selectedValue = selectedOptions[0];
234
241
  const optionElement = this._select
235
242
  .getElement()
236
- .querySelector(`option[value="${CSS.escape(selectedValue)}"]`);
243
+ ?.querySelector(`option[value="${CSS.escape(selectedValue)}"]`);
237
244
  this._searchInputElement.value = optionElement
238
245
  ? optionElement.textContent || ''
239
246
  : '';
@@ -15,17 +15,17 @@ export const DefaultConfig: KTSelectConfigInterface = {
15
15
  // Data Handling
16
16
  items: [], // Static list of options
17
17
  isLoading: false, // Indicates if options are being loaded asynchronously
18
- onFetch: null, // Callback function to fetch options asynchronously
18
+ onFetch: undefined, // Callback function to fetch options asynchronously
19
19
 
20
20
  // Remote Data Configuration
21
21
  remote: false, // Enable/disable remote data fetching
22
- dataUrl: null, // URL to fetch options from
23
- apiDataProperty: null, // Property in the response object that contains the options
22
+ dataUrl: undefined, // URL to fetch options from
23
+ apiDataProperty: undefined, // Property in the response object that contains the options
24
24
  remoteErrorMessage: 'Failed to load data', // Error message to display if remote data fetch fails
25
25
 
26
26
  // Field Mapping
27
- dataValueField: null, // Property in the option object that contains the value (default: 'id')
28
- dataFieldText: null, // Property in the option object that contains the text (default: 'title')
27
+ dataValueField: undefined, // Property in the option object that contains the value (default: 'id')
28
+ dataFieldText: undefined, // Property in the option object that contains the text (default: 'title')
29
29
 
30
30
  // Search Configuration
31
31
  searchParam: '', // Query parameter for API search requests
@@ -60,7 +60,7 @@ export const DefaultConfig: KTSelectConfigInterface = {
60
60
  clearAllText: 'Clear all', // Text for the "Clear All" option (if implemented)
61
61
  enableSelectAll: false, // Enable/disable "Select All" button for multi-select
62
62
  showSelectedCount: true, // Show the number of selected options in multi-select mode
63
- renderSelected: null, // Custom function to render the selected value(s) in the display area
63
+ renderSelected: undefined, // Custom function to render the selected value(s) in the display area
64
64
 
65
65
  // Accessibility & Usability
66
66
  label: 'Select an option', // Label for the select component (for screen readers)
@@ -69,10 +69,10 @@ export const DefaultConfig: KTSelectConfigInterface = {
69
69
  // Dropdown Configuration
70
70
  dropdownZindex: 105, // Initial z-index value for the dropdown
71
71
  dropdownContainer: null, // Container element for the dropdown
72
- dropdownPlacement: null,
72
+ dropdownPlacement: undefined,
73
73
  dropdownFlip: false,
74
74
  dropdownPreventOverflow: false,
75
- dropdownStrategy: null,
75
+ dropdownStrategy: undefined,
76
76
  dropdownWidth: null, // Custom width for dropdown (e.g., '300px'), null to match toggle element width
77
77
  closeOnOtherOpen: true, // Close other open dropdowns when this one opens
78
78
  dispatchGlobalEvents: true, // Dispatch events on document for global listeners (jQuery compatibility)
@@ -112,7 +112,7 @@ export interface KTSelectConfigInterface {
112
112
  clearAllText?: string;
113
113
  enableSelectAll?: boolean;
114
114
  showSelectedCount?: boolean;
115
- renderSelected?: (selectedOptions: any[]) => string; // Assuming any[] for now, adjust based on your option data structure
115
+ renderSelected?: (selectedOptions: string[]) => string;
116
116
 
117
117
  // Accessibility & Usability
118
118
  label?: string;
@@ -201,16 +201,17 @@ export class KTSelectState {
201
201
  }
202
202
 
203
203
  private _initDefaultConfig(
204
- config: KTSelectConfigInterface,
204
+ config?: KTSelectConfigInterface,
205
205
  ): KTSelectConfigInterface {
206
+ const resolvedConfig: Partial<KTSelectConfigInterface> = config ?? {};
206
207
  return {
207
208
  ...DefaultConfig,
208
- ...config,
209
- ...config.config,
210
- };
209
+ ...resolvedConfig,
210
+ ...resolvedConfig.config,
211
+ } as KTSelectConfigInterface;
211
212
  }
212
213
 
213
- public setItems(items?: any[], query?: string): Promise<void> {
214
+ public setItems(items?: KTSelectOption[], query?: string): Promise<void> {
214
215
  return new Promise<void>((resolve, reject) => {
215
216
  if (items) {
216
217
  this._config.items = items;
@@ -127,7 +127,7 @@ export class KTSelectDropdown extends KTComponent {
127
127
  /**
128
128
  * Handle clicks outside the dropdown
129
129
  */
130
- private _handleOutsideClick(event: MouseEvent): void {
130
+ private _handleOutsideClick(event: Event): void {
131
131
  if (!this._isOpen) return;
132
132
 
133
133
  const target = event.target as HTMLElement;
@@ -13,16 +13,26 @@ export class KTSelectOption extends KTComponent {
13
13
  protected override readonly _config: KTSelectConfigInterface; // Holds option-specific data from data-kt-*
14
14
  private _globalConfig: KTSelectConfigInterface; // Main select's config
15
15
 
16
+ private _elementWithInstance(): HTMLElement & { instance?: KTSelectOption } {
17
+ return this._element as HTMLElement & { instance?: KTSelectOption };
18
+ }
19
+
16
20
  constructor(element: HTMLElement, config?: KTSelectConfigInterface) {
17
21
  super();
18
22
 
19
23
  // Always initialize a new option instance
20
24
  this._init(element);
21
- this._globalConfig = config;
25
+ this._globalConfig = (config ?? {}) as KTSelectConfigInterface;
22
26
  this._buildConfig();
23
27
 
24
28
  // Clean the config
25
- this._config = (this._config as any)[''] || {};
29
+ const configRecord = this._config as unknown as Record<
30
+ string,
31
+ KTSelectConfigInterface
32
+ >;
33
+ this._config =
34
+ (configRecord[''] as KTSelectConfigInterface) ||
35
+ ({} as KTSelectConfigInterface);
26
36
 
27
37
  // Add the option config to the global config
28
38
  // Ensure optionsConfig is initialized
@@ -42,7 +52,7 @@ export class KTSelectOption extends KTComponent {
42
52
 
43
53
  // Don't store in KTData to avoid Singleton pattern issues
44
54
  // Each option should be a unique instance
45
- (element as any).instance = this;
55
+ this._elementWithInstance().instance = this;
46
56
  }
47
57
 
48
58
  public get id(): string {
@@ -61,7 +71,7 @@ export class KTSelectOption extends KTComponent {
61
71
  * Gathers all necessary data for rendering this option,
62
72
  * including standard HTML attributes and custom data-kt-* attributes.
63
73
  */
64
- public getOptionDataForTemplate(): Record<string, any> {
74
+ public getOptionDataForTemplate(): Record<string, unknown> {
65
75
  const el = this.getHTMLOptionElement();
66
76
  const text = el.textContent || '';
67
77
  return {
@@ -22,6 +22,10 @@ export class KTSelectRemote {
22
22
  private _lastQuery: string = '';
23
23
  private _element: HTMLElement | null = null;
24
24
 
25
+ private _isRecord(value: unknown): value is Record<string, unknown> {
26
+ return typeof value === 'object' && value !== null;
27
+ }
28
+
25
29
  /**
26
30
  * Constructor
27
31
  * @param config KTSelect configuration
@@ -54,13 +58,13 @@ export class KTSelectRemote {
54
58
  this._dispatchEvent('remoteSearchStart');
55
59
 
56
60
  return fetch(url)
57
- .then((response: Response): Promise<any> => {
61
+ .then((response: Response): Promise<unknown> => {
58
62
  if (!response.ok) {
59
63
  throw new Error(`HTTP error! Status: ${response.status}`);
60
64
  }
61
65
  return response.json();
62
66
  })
63
- .then((data: any): KTSelectOptionData[] => {
67
+ .then((data: unknown): KTSelectOptionData[] => {
64
68
  // Process the data
65
69
  return this._processData(data);
66
70
  })
@@ -144,25 +148,30 @@ export class KTSelectRemote {
144
148
  * @param data API response data
145
149
  * @returns Array of KTSelectOptionData
146
150
  */
147
- private _processData(data: any): KTSelectOptionData[] {
151
+ private _processData(data: unknown): KTSelectOptionData[] {
148
152
  try {
149
- let processedData = data;
153
+ let processedData: unknown = data;
154
+ const dataRecord = this._isRecord(data) ? data : null;
150
155
 
151
156
  // Extract data from the API property if specified
152
- if (this._config.apiDataProperty && data[this._config.apiDataProperty]) {
157
+ if (
158
+ this._config.apiDataProperty &&
159
+ dataRecord &&
160
+ this._config.apiDataProperty in dataRecord
161
+ ) {
153
162
  // If pagination metadata is available, extract it
154
163
  if (this._config.pagination) {
155
- if (data.total_pages) {
156
- this._totalPages = data.total_pages;
164
+ if (typeof dataRecord.total_pages === 'number') {
165
+ this._totalPages = dataRecord.total_pages;
157
166
  }
158
- if (data.total) {
167
+ if (typeof dataRecord.total === 'number') {
159
168
  this._totalPages = Math.ceil(
160
- data.total / (this._config.paginationLimit || 10),
169
+ dataRecord.total / (this._config.paginationLimit || 10),
161
170
  );
162
171
  }
163
172
  }
164
173
 
165
- processedData = data[this._config.apiDataProperty];
174
+ processedData = dataRecord[this._config.apiDataProperty];
166
175
  }
167
176
 
168
177
  // Ensure data is an array
@@ -172,46 +181,48 @@ export class KTSelectRemote {
172
181
  }
173
182
 
174
183
  // Map data to KTSelectOptionData format
175
- const mappedData = processedData.map((item: any): KTSelectOptionData => {
176
- const mappedItem = this._mapItemToOption(item);
177
-
178
- // Add logging to trace data path extraction
179
- if (
180
- this._config.dataValueField &&
181
- this._config.dataValueField.includes('.')
182
- ) {
183
- // For nested paths, verify extraction worked
184
- const parts = this._config.dataValueField.split('.');
185
- let nestedValue = item;
186
-
187
- // Try to navigate to the value manually for verification
188
- for (const part of parts) {
189
- if (
190
- nestedValue &&
191
- typeof nestedValue === 'object' &&
192
- part in nestedValue
193
- ) {
194
- nestedValue = nestedValue[part];
195
- } else {
196
- nestedValue = null;
197
- break;
184
+ const mappedData = processedData.map(
185
+ (item: unknown): KTSelectOptionData => {
186
+ const mappedItem = this._mapItemToOption(item);
187
+
188
+ // Add logging to trace data path extraction
189
+ if (
190
+ this._config.dataValueField &&
191
+ this._config.dataValueField.includes('.')
192
+ ) {
193
+ // For nested paths, verify extraction worked
194
+ const parts = this._config.dataValueField.split('.');
195
+ let nestedValue: unknown = item;
196
+
197
+ // Try to navigate to the value manually for verification
198
+ for (const part of parts) {
199
+ if (
200
+ nestedValue &&
201
+ typeof nestedValue === 'object' &&
202
+ part in nestedValue
203
+ ) {
204
+ nestedValue = (nestedValue as Record<string, unknown>)[part];
205
+ } else {
206
+ nestedValue = null;
207
+ break;
208
+ }
198
209
  }
199
- }
200
210
 
201
- // If we found a value, verify it matches what was extracted
202
- if (nestedValue !== null && nestedValue !== undefined) {
203
- const expectedValue = String(nestedValue);
211
+ // If we found a value, verify it matches what was extracted
212
+ if (nestedValue !== null && nestedValue !== undefined) {
213
+ const expectedValue = String(nestedValue);
204
214
 
205
- if (mappedItem.id !== expectedValue && expectedValue) {
206
- console.warn(
207
- `Value mismatch! Path: ${this._config.dataValueField}, Expected: ${expectedValue}, Got: ${mappedItem.id}`,
208
- );
215
+ if (mappedItem.id !== expectedValue && expectedValue) {
216
+ console.warn(
217
+ `Value mismatch! Path: ${this._config.dataValueField}, Expected: ${expectedValue}, Got: ${mappedItem.id}`,
218
+ );
219
+ }
209
220
  }
210
221
  }
211
- }
212
222
 
213
- return mappedItem;
214
- });
223
+ return mappedItem;
224
+ },
225
+ );
215
226
 
216
227
  return mappedData;
217
228
  } catch (error) {
@@ -227,19 +238,19 @@ export class KTSelectRemote {
227
238
  * @param item Data item from API
228
239
  * @returns KTSelectOptionData object
229
240
  */
230
- private _mapItemToOption(item: any): KTSelectOptionData {
241
+ private _mapItemToOption(item: unknown): KTSelectOptionData {
231
242
  // Get the field mapping from config with fallbacks for common field names
232
243
  const valueField = this._config.dataValueField || 'id';
233
244
  const labelField = this._config.dataFieldText || 'title';
234
245
 
235
246
  // Extract values using improved getValue function
236
- const getValue = (obj: any, path: string): any => {
247
+ const getValue = (obj: unknown, path: string): unknown => {
237
248
  if (!path || !obj) return null;
238
249
 
239
250
  try {
240
251
  // Handle dot notation to access nested properties
241
252
  const parts = path.split('.');
242
- let result = obj;
253
+ let result: unknown = obj;
243
254
 
244
255
  for (const part of parts) {
245
256
  if (
@@ -249,7 +260,7 @@ export class KTSelectRemote {
249
260
  ) {
250
261
  return null;
251
262
  }
252
- result = result[part];
263
+ result = (result as Record<string, unknown>)[part];
253
264
  }
254
265
 
255
266
  return result;
@@ -261,12 +272,13 @@ export class KTSelectRemote {
261
272
 
262
273
  // Get ID and ensure it's a string
263
274
  let id = getValue(item, valueField);
275
+ const itemRecord = this._isRecord(item) ? item : {};
264
276
  if (id === null || id === undefined) {
265
277
  // Try common fallback fields for ID
266
278
  const fallbackFields = ['id', 'value', 'key', 'pk'];
267
279
  for (const field of fallbackFields) {
268
- if (item[field] !== null && item[field] !== undefined) {
269
- id = String(item[field]);
280
+ if (itemRecord[field] !== null && itemRecord[field] !== undefined) {
281
+ id = String(itemRecord[field]);
270
282
  break;
271
283
  }
272
284
  }
@@ -292,8 +304,8 @@ export class KTSelectRemote {
292
304
  'description',
293
305
  ];
294
306
  for (const field of fallbackFields) {
295
- if (item[field] !== null && item[field] !== undefined) {
296
- title = String(item[field]);
307
+ if (itemRecord[field] !== null && itemRecord[field] !== undefined) {
308
+ title = String(itemRecord[field]);
297
309
  break;
298
310
  }
299
311
  }
@@ -308,10 +320,10 @@ export class KTSelectRemote {
308
320
 
309
321
  // Create the option object with consistent structure
310
322
  const result: KTSelectOptionData = {
311
- id: id,
312
- title: title,
313
- selected: Boolean(item.selected),
314
- disabled: Boolean(item.disabled),
323
+ id: String(id),
324
+ title: String(title),
325
+ selected: Boolean(itemRecord.selected),
326
+ disabled: Boolean(itemRecord.disabled),
315
327
  };
316
328
 
317
329
  return result;
@@ -10,7 +10,7 @@ import { filterOptions, FocusManager, EventManager } from './utils';
10
10
 
11
11
  export class KTSelectSearch {
12
12
  private _select: KTSelect;
13
- private _searchInput: HTMLInputElement;
13
+ private _searchInput: HTMLInputElement | null;
14
14
  private _noResultsElement: HTMLElement | null = null;
15
15
  private _originalOptionContents = new Map<string, string>();
16
16
  private _eventManager: EventManager;
@@ -18,7 +18,7 @@ export class KTSelectSearch {
18
18
  private _config: KTSelectConfigInterface;
19
19
 
20
20
  // Public handler for search input (made public for event binding)
21
- public handleSearchInput: (...args: any[]) => void;
21
+ public handleSearchInput: (event: Event) => void;
22
22
 
23
23
  constructor(select: KTSelect) {
24
24
  this._select = select;
@@ -60,7 +60,7 @@ export class KTSelectSearch {
60
60
  this._eventManager.addListener(this._searchInput, 'blur', () => {
61
61
  // Small delay to prevent race conditions with selection
62
62
  setTimeout(() => {
63
- if (!this._searchInput.value) {
63
+ if (!this._searchInput?.value) {
64
64
  this._resetAllOptions();
65
65
  this.clearSearch();
66
66
  }
@@ -74,12 +74,12 @@ export class KTSelectSearch {
74
74
  ) {
75
75
  this._select
76
76
  .getElement()
77
- .addEventListener('remoteSearchStart', () => {
77
+ ?.addEventListener('remoteSearchStart', () => {
78
78
  // Reset focused option when remote search starts
79
79
  this._focusManager.resetFocus();
80
80
  });
81
81
 
82
- this._select.getElement().addEventListener('remoteSearchEnd', () => {
82
+ this._select.getElement()?.addEventListener('remoteSearchEnd', () => {
83
83
  // After remote search completes, refresh our option cache
84
84
  this.refreshOptionCache();
85
85
  });
@@ -88,7 +88,7 @@ export class KTSelectSearch {
88
88
  // Listen for dropdown close to reset options - ATTACH TO WRAPPER
89
89
  this._select
90
90
  .getWrapperElement()
91
- .addEventListener('dropdown.close', () => {
91
+ ?.addEventListener('dropdown.close', () => {
92
92
  this._focusManager.resetFocus();
93
93
  const config = this._select.getConfig();
94
94
 
@@ -98,7 +98,9 @@ export class KTSelectSearch {
98
98
  // Respect clearSearchOnClose config option
99
99
  if (config.clearSearchOnClose) {
100
100
  // Clear the search input field
101
- this._searchInput.value = '';
101
+ if (this._searchInput) {
102
+ this._searchInput.value = '';
103
+ }
102
104
  // Reset all options to their original state
103
105
  this._resetAllOptions();
104
106
  // Clear any "no results" message
@@ -116,7 +118,7 @@ export class KTSelectSearch {
116
118
  });
117
119
 
118
120
  // Clear highlights when an option is selected - ATTACH TO ORIGINAL SELECT (standard 'change' event)
119
- this._select.getElement().addEventListener('change', () => {
121
+ this._select.getElement()?.addEventListener('change', () => {
120
122
  this.clearSearch();
121
123
 
122
124
  // Close dropdown only for single select mode, and only if closeOnEnter is not false
@@ -131,7 +133,7 @@ export class KTSelectSearch {
131
133
  // Consolidated 'dropdown.show' event listener - ATTACH TO WRAPPER
132
134
  this._select
133
135
  .getWrapperElement()
134
- .addEventListener('dropdown.show', () => {
136
+ ?.addEventListener('dropdown.show', () => {
135
137
  this._focusManager.resetFocus(); // Always clear previous focus state
136
138
 
137
139
  if (this._searchInput?.value) {
@@ -205,7 +207,7 @@ export class KTSelectSearch {
205
207
  if (attempt < maxAttempts) {
206
208
  this._focusSearchInputWithRetry(attempt + 1);
207
209
  }
208
- } catch (error) {
210
+ } catch {
209
211
  // Focus failed with error, retry if we haven't exceeded max attempts
210
212
  if (attempt < maxAttempts) {
211
213
  this._focusSearchInputWithRetry(attempt + 1);
@@ -223,25 +225,26 @@ export class KTSelectSearch {
223
225
  /**
224
226
  * Handles keydown events on the search input for navigation and actions.
225
227
  */
226
- private _handleSearchKeyDown(event: KeyboardEvent): void {
227
- const key = event.key;
228
+ private _handleSearchKeyDown(event: Event): void {
229
+ const keyEvent = event as KeyboardEvent;
230
+ const key = keyEvent.key;
228
231
 
229
232
  switch (key) {
230
233
  case ' ': // Spacebar
231
234
  // Do nothing, allow space to be typed into the input
232
235
  // Stop propagation to prevent parent handlers from processing this event
233
- event.stopPropagation();
236
+ keyEvent.stopPropagation();
234
237
  break;
235
238
  case 'ArrowDown':
236
- event.preventDefault();
239
+ keyEvent.preventDefault();
237
240
  this._focusManager.focusNext();
238
241
  break;
239
242
  case 'ArrowUp':
240
- event.preventDefault();
243
+ keyEvent.preventDefault();
241
244
  this._focusManager.focusPrevious();
242
245
  break;
243
- case 'Enter':
244
- event.preventDefault();
246
+ case 'Enter': {
247
+ keyEvent.preventDefault();
245
248
  // Use currently focused option (from arrow keys); only fall back to first if none focused
246
249
  const optionToSelect =
247
250
  this._focusManager.getFocusedOption() ??
@@ -272,9 +275,12 @@ export class KTSelectSearch {
272
275
  }
273
276
  }
274
277
  break;
278
+ }
275
279
  case 'Escape':
276
- event.preventDefault();
277
- this._searchInput.value = '';
280
+ keyEvent.preventDefault();
281
+ if (this._searchInput) {
282
+ this._searchInput.value = '';
283
+ }
278
284
  this.clearSearch();
279
285
  this._resetAllOptions();
280
286
  this._clearNoResultsMessage();
@@ -342,8 +348,9 @@ export class KTSelectSearch {
342
348
 
343
349
  // For remote search, KTSelect component handles it.
344
350
  // KTSelect will call refreshAfterSearch on this module when remote data is updated.
351
+ const minLength = config.searchMinLength ?? 0;
345
352
  if (config.remote && config.searchParam) {
346
- if (query.length < config.searchMinLength) {
353
+ if (query.length < minLength) {
347
354
  this._resetAllOptions();
348
355
  this._clearNoResultsMessage();
349
356
  this._focusManager.focusFirst(); // Focus first if query too short
@@ -352,7 +359,7 @@ export class KTSelectSearch {
352
359
  }
353
360
 
354
361
  // For local search
355
- if (query.length >= config.searchMinLength) {
362
+ if (query.length >= minLength) {
356
363
  this._filterOptions(query);
357
364
  this._focusManager.focusFirst(); // Focus first visible option after local filtering
358
365
  } else {
@@ -377,12 +384,8 @@ export class KTSelectSearch {
377
384
  // Restore original content before filtering, so highlighting is applied fresh.
378
385
  this._restoreOptionContentsBeforeFilter();
379
386
 
380
- const visibleCount = filterOptions(
381
- options,
382
- query,
383
- config,
384
- dropdownElement,
385
- (count) => this._handleNoResults(count),
387
+ filterOptions(options, query, config, dropdownElement, (count) =>
388
+ this._handleNoResults(count),
386
389
  );
387
390
 
388
391
  this._select.updateSelectAllButtonState();