@keenthemes/ktui 1.1.5 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/README.md +24 -0
  2. package/dist/ktui.js +11639 -11035
  3. package/dist/ktui.min.js +1 -1
  4. package/dist/ktui.min.js.map +1 -1
  5. package/dist/styles.css +140 -32
  6. package/lib/cjs/components/accordion/accordion.d.ts +32 -0
  7. package/lib/cjs/components/accordion/accordion.d.ts.map +1 -0
  8. package/lib/cjs/components/accordion/index.d.ts +7 -0
  9. package/lib/cjs/components/accordion/index.d.ts.map +1 -0
  10. package/lib/cjs/components/accordion/types.d.ts +15 -0
  11. package/lib/cjs/components/accordion/types.d.ts.map +1 -0
  12. package/lib/cjs/components/collapse/collapse.d.ts +28 -0
  13. package/lib/cjs/components/collapse/collapse.d.ts.map +1 -0
  14. package/lib/cjs/components/collapse/collapse.js +0 -2
  15. package/lib/cjs/components/collapse/collapse.js.map +1 -1
  16. package/lib/cjs/components/collapse/index.d.ts +7 -0
  17. package/lib/cjs/components/collapse/index.d.ts.map +1 -0
  18. package/lib/cjs/components/collapse/types.d.ts +15 -0
  19. package/lib/cjs/components/collapse/types.d.ts.map +1 -0
  20. package/lib/cjs/components/component.d.ts +44 -0
  21. package/lib/cjs/components/component.d.ts.map +1 -0
  22. package/lib/cjs/components/component.js +3 -1
  23. package/lib/cjs/components/component.js.map +1 -1
  24. package/lib/cjs/components/constants.d.ts +6 -0
  25. package/lib/cjs/components/constants.d.ts.map +1 -0
  26. package/lib/cjs/components/datatable/datatable-checkbox.d.ts +16 -0
  27. package/lib/cjs/components/datatable/datatable-checkbox.d.ts.map +1 -0
  28. package/lib/cjs/components/datatable/datatable-sort.d.ts +16 -0
  29. package/lib/cjs/components/datatable/datatable-sort.d.ts.map +1 -0
  30. package/lib/cjs/components/datatable/datatable-sort.js +1 -2
  31. package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
  32. package/lib/cjs/components/datatable/datatable.d.ts +339 -0
  33. package/lib/cjs/components/datatable/datatable.d.ts.map +1 -0
  34. package/lib/cjs/components/datatable/datatable.js +45 -23
  35. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  36. package/lib/cjs/components/datatable/index.d.ts +7 -0
  37. package/lib/cjs/components/datatable/index.d.ts.map +1 -0
  38. package/lib/cjs/components/datatable/types.d.ts +166 -0
  39. package/lib/cjs/components/datatable/types.d.ts.map +1 -0
  40. package/lib/cjs/components/dismiss/dismiss.d.ts +30 -0
  41. package/lib/cjs/components/dismiss/dismiss.d.ts.map +1 -0
  42. package/lib/cjs/components/dismiss/index.d.ts +7 -0
  43. package/lib/cjs/components/dismiss/index.d.ts.map +1 -0
  44. package/lib/cjs/components/dismiss/types.d.ts +15 -0
  45. package/lib/cjs/components/dismiss/types.d.ts.map +1 -0
  46. package/lib/cjs/components/drawer/drawer.d.ts +63 -0
  47. package/lib/cjs/components/drawer/drawer.d.ts.map +1 -0
  48. package/lib/cjs/components/drawer/drawer.js +21 -9
  49. package/lib/cjs/components/drawer/drawer.js.map +1 -1
  50. package/lib/cjs/components/drawer/index.d.ts +7 -0
  51. package/lib/cjs/components/drawer/index.d.ts.map +1 -0
  52. package/lib/cjs/components/drawer/types.d.ts +27 -0
  53. package/lib/cjs/components/drawer/types.d.ts.map +1 -0
  54. package/lib/cjs/components/dropdown/dropdown.d.ts +71 -0
  55. package/lib/cjs/components/dropdown/dropdown.d.ts.map +1 -0
  56. package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
  57. package/lib/cjs/components/dropdown/index.d.ts +7 -0
  58. package/lib/cjs/components/dropdown/index.d.ts.map +1 -0
  59. package/lib/cjs/components/dropdown/types.d.ts +27 -0
  60. package/lib/cjs/components/dropdown/types.d.ts.map +1 -0
  61. package/lib/cjs/components/image-input/image-input.d.ts +42 -0
  62. package/lib/cjs/components/image-input/image-input.d.ts.map +1 -0
  63. package/lib/cjs/components/image-input/index.d.ts +7 -0
  64. package/lib/cjs/components/image-input/index.d.ts.map +1 -0
  65. package/lib/cjs/components/image-input/types.d.ts +12 -0
  66. package/lib/cjs/components/image-input/types.d.ts.map +1 -0
  67. package/lib/cjs/components/modal/index.d.ts +7 -0
  68. package/lib/cjs/components/modal/index.d.ts.map +1 -0
  69. package/lib/cjs/components/modal/modal.d.ts +45 -0
  70. package/lib/cjs/components/modal/modal.d.ts.map +1 -0
  71. package/lib/cjs/components/modal/types.d.ts +21 -0
  72. package/lib/cjs/components/modal/types.d.ts.map +1 -0
  73. package/lib/cjs/components/rating/index.d.ts +7 -0
  74. package/lib/cjs/components/rating/index.d.ts.map +1 -0
  75. package/lib/cjs/components/rating/index.js +10 -0
  76. package/lib/cjs/components/rating/index.js.map +1 -0
  77. package/lib/cjs/components/rating/rating.d.ts +31 -0
  78. package/lib/cjs/components/rating/rating.d.ts.map +1 -0
  79. package/lib/cjs/components/rating/rating.js +239 -0
  80. package/lib/cjs/components/rating/rating.js.map +1 -0
  81. package/lib/cjs/components/rating/types.d.ts +25 -0
  82. package/lib/cjs/components/rating/types.d.ts.map +1 -0
  83. package/lib/cjs/components/rating/types.js +7 -0
  84. package/lib/cjs/components/rating/types.js.map +1 -0
  85. package/lib/cjs/components/reparent/index.d.ts +7 -0
  86. package/lib/cjs/components/reparent/index.d.ts.map +1 -0
  87. package/lib/cjs/components/reparent/reparent.d.ts +25 -0
  88. package/lib/cjs/components/reparent/reparent.d.ts.map +1 -0
  89. package/lib/cjs/components/reparent/types.d.ts +13 -0
  90. package/lib/cjs/components/reparent/types.d.ts.map +1 -0
  91. package/lib/cjs/components/repeater/index.d.ts +7 -0
  92. package/lib/cjs/components/repeater/index.d.ts.map +1 -0
  93. package/lib/cjs/components/repeater/index.js +10 -0
  94. package/lib/cjs/components/repeater/index.js.map +1 -0
  95. package/lib/cjs/components/repeater/repeater.d.ts +33 -0
  96. package/lib/cjs/components/repeater/repeater.d.ts.map +1 -0
  97. package/lib/cjs/components/repeater/repeater.js +173 -0
  98. package/lib/cjs/components/repeater/repeater.js.map +1 -0
  99. package/lib/cjs/components/repeater/types.d.ts +18 -0
  100. package/lib/cjs/components/repeater/types.d.ts.map +1 -0
  101. package/lib/cjs/components/repeater/types.js +7 -0
  102. package/lib/cjs/components/repeater/types.js.map +1 -0
  103. package/lib/cjs/components/scrollable/index.d.ts +7 -0
  104. package/lib/cjs/components/scrollable/index.d.ts.map +1 -0
  105. package/lib/cjs/components/scrollable/scrollable.d.ts +37 -0
  106. package/lib/cjs/components/scrollable/scrollable.d.ts.map +1 -0
  107. package/lib/cjs/components/scrollable/types.d.ts +15 -0
  108. package/lib/cjs/components/scrollable/types.d.ts.map +1 -0
  109. package/lib/cjs/components/scrollspy/index.d.ts +7 -0
  110. package/lib/cjs/components/scrollspy/index.d.ts.map +1 -0
  111. package/lib/cjs/components/scrollspy/scrollspy.d.ts +35 -0
  112. package/lib/cjs/components/scrollspy/scrollspy.d.ts.map +1 -0
  113. package/lib/cjs/components/scrollspy/types.d.ts +14 -0
  114. package/lib/cjs/components/scrollspy/types.d.ts.map +1 -0
  115. package/lib/cjs/components/scrollto/index.d.ts +7 -0
  116. package/lib/cjs/components/scrollto/index.d.ts.map +1 -0
  117. package/lib/cjs/components/scrollto/scrollto.d.ts +28 -0
  118. package/lib/cjs/components/scrollto/scrollto.d.ts.map +1 -0
  119. package/lib/cjs/components/scrollto/scrollto.js +0 -2
  120. package/lib/cjs/components/scrollto/scrollto.js.map +1 -1
  121. package/lib/cjs/components/scrollto/types.d.ts +14 -0
  122. package/lib/cjs/components/scrollto/types.d.ts.map +1 -0
  123. package/lib/cjs/components/select/combobox.d.ts +52 -0
  124. package/lib/cjs/components/select/combobox.d.ts.map +1 -0
  125. package/lib/cjs/components/select/combobox.js.map +1 -1
  126. package/lib/cjs/components/select/config.d.ts +105 -0
  127. package/lib/cjs/components/select/config.d.ts.map +1 -0
  128. package/lib/cjs/components/select/dropdown.d.ts +101 -0
  129. package/lib/cjs/components/select/dropdown.d.ts.map +1 -0
  130. package/lib/cjs/components/select/dropdown.js.map +1 -1
  131. package/lib/cjs/components/select/index.d.ts +13 -0
  132. package/lib/cjs/components/select/index.d.ts.map +1 -0
  133. package/lib/cjs/components/select/option.d.ts +23 -0
  134. package/lib/cjs/components/select/option.d.ts.map +1 -0
  135. package/lib/cjs/components/select/remote.d.ts +91 -0
  136. package/lib/cjs/components/select/remote.d.ts.map +1 -0
  137. package/lib/cjs/components/select/remote.js.map +1 -1
  138. package/lib/cjs/components/select/search.d.ts +67 -0
  139. package/lib/cjs/components/select/search.d.ts.map +1 -0
  140. package/lib/cjs/components/select/search.js +9 -5
  141. package/lib/cjs/components/select/search.js.map +1 -1
  142. package/lib/cjs/components/select/select.d.ts +427 -0
  143. package/lib/cjs/components/select/select.d.ts.map +1 -0
  144. package/lib/cjs/components/select/select.js +25 -5
  145. package/lib/cjs/components/select/select.js.map +1 -1
  146. package/lib/cjs/components/select/tags.d.ts +32 -0
  147. package/lib/cjs/components/select/tags.d.ts.map +1 -0
  148. package/lib/cjs/components/select/tags.js.map +1 -1
  149. package/lib/cjs/components/select/templates.d.ts +79 -0
  150. package/lib/cjs/components/select/templates.d.ts.map +1 -0
  151. package/lib/cjs/components/select/templates.js.map +1 -1
  152. package/lib/cjs/components/select/types.d.ts +23 -0
  153. package/lib/cjs/components/select/types.d.ts.map +1 -0
  154. package/lib/cjs/components/select/utils.d.ts +130 -0
  155. package/lib/cjs/components/select/utils.d.ts.map +1 -0
  156. package/lib/cjs/components/select/utils.js +10 -0
  157. package/lib/cjs/components/select/utils.js.map +1 -1
  158. package/lib/cjs/components/stepper/index.d.ts +7 -0
  159. package/lib/cjs/components/stepper/index.d.ts.map +1 -0
  160. package/lib/cjs/components/stepper/stepper.d.ts +53 -0
  161. package/lib/cjs/components/stepper/stepper.d.ts.map +1 -0
  162. package/lib/cjs/components/stepper/types.d.ts +12 -0
  163. package/lib/cjs/components/stepper/types.d.ts.map +1 -0
  164. package/lib/cjs/components/sticky/index.d.ts +7 -0
  165. package/lib/cjs/components/sticky/index.d.ts.map +1 -0
  166. package/lib/cjs/components/sticky/sticky.d.ts +51 -0
  167. package/lib/cjs/components/sticky/sticky.d.ts.map +1 -0
  168. package/lib/cjs/components/sticky/sticky.js +104 -24
  169. package/lib/cjs/components/sticky/sticky.js.map +1 -1
  170. package/lib/cjs/components/sticky/types.d.ts +28 -0
  171. package/lib/cjs/components/sticky/types.d.ts.map +1 -0
  172. package/lib/cjs/components/tabs/index.d.ts +7 -0
  173. package/lib/cjs/components/tabs/index.d.ts.map +1 -0
  174. package/lib/cjs/components/tabs/tabs.d.ts +38 -0
  175. package/lib/cjs/components/tabs/tabs.d.ts.map +1 -0
  176. package/lib/cjs/components/tabs/types.d.ts +12 -0
  177. package/lib/cjs/components/tabs/types.d.ts.map +1 -0
  178. package/lib/cjs/components/theme-switch/index.d.ts +7 -0
  179. package/lib/cjs/components/theme-switch/index.d.ts.map +1 -0
  180. package/lib/cjs/components/theme-switch/theme-switch.d.ts +33 -0
  181. package/lib/cjs/components/theme-switch/theme-switch.d.ts.map +1 -0
  182. package/lib/cjs/components/theme-switch/theme-switch.js +0 -2
  183. package/lib/cjs/components/theme-switch/theme-switch.js.map +1 -1
  184. package/lib/cjs/components/theme-switch/types.d.ts +13 -0
  185. package/lib/cjs/components/theme-switch/types.d.ts.map +1 -0
  186. package/lib/cjs/components/toast/index.d.ts +7 -0
  187. package/lib/cjs/components/toast/index.d.ts.map +1 -0
  188. package/lib/cjs/components/toast/toast.d.ts +76 -0
  189. package/lib/cjs/components/toast/toast.d.ts.map +1 -0
  190. package/lib/cjs/components/toast/toast.js +1 -2
  191. package/lib/cjs/components/toast/toast.js.map +1 -1
  192. package/lib/cjs/components/toast/types.d.ts +146 -0
  193. package/lib/cjs/components/toast/types.d.ts.map +1 -0
  194. package/lib/cjs/components/toggle/index.d.ts +7 -0
  195. package/lib/cjs/components/toggle/index.d.ts.map +1 -0
  196. package/lib/cjs/components/toggle/toggle.d.ts +31 -0
  197. package/lib/cjs/components/toggle/toggle.d.ts.map +1 -0
  198. package/lib/cjs/components/toggle/types.d.ts +17 -0
  199. package/lib/cjs/components/toggle/types.d.ts.map +1 -0
  200. package/lib/cjs/components/toggle-password/index.d.ts +7 -0
  201. package/lib/cjs/components/toggle-password/index.d.ts.map +1 -0
  202. package/lib/cjs/components/toggle-password/toggle-password.d.ts +32 -0
  203. package/lib/cjs/components/toggle-password/toggle-password.d.ts.map +1 -0
  204. package/lib/cjs/components/toggle-password/types.d.ts +12 -0
  205. package/lib/cjs/components/toggle-password/types.d.ts.map +1 -0
  206. package/lib/cjs/components/tooltip/index.d.ts +7 -0
  207. package/lib/cjs/components/tooltip/index.d.ts.map +1 -0
  208. package/lib/cjs/components/tooltip/tooltip.d.ts +46 -0
  209. package/lib/cjs/components/tooltip/tooltip.d.ts.map +1 -0
  210. package/lib/cjs/components/tooltip/types.d.ts +26 -0
  211. package/lib/cjs/components/tooltip/types.d.ts.map +1 -0
  212. package/lib/cjs/helpers/data.d.ts +13 -0
  213. package/lib/cjs/helpers/data.d.ts.map +1 -0
  214. package/lib/cjs/helpers/dom.d.ts +42 -0
  215. package/lib/cjs/helpers/dom.d.ts.map +1 -0
  216. package/lib/cjs/helpers/dom.js +0 -2
  217. package/lib/cjs/helpers/dom.js.map +1 -1
  218. package/lib/cjs/helpers/event-handler.d.ts +14 -0
  219. package/lib/cjs/helpers/event-handler.d.ts.map +1 -0
  220. package/lib/cjs/helpers/utils.d.ts +25 -0
  221. package/lib/cjs/helpers/utils.d.ts.map +1 -0
  222. package/lib/cjs/index.d.ts +114 -0
  223. package/lib/cjs/index.d.ts.map +1 -0
  224. package/lib/cjs/index.js +9 -1
  225. package/lib/cjs/index.js.map +1 -1
  226. package/lib/cjs/types.d.ts +17 -0
  227. package/lib/cjs/types.d.ts.map +1 -0
  228. package/lib/esm/components/accordion/accordion.d.ts +32 -0
  229. package/lib/esm/components/accordion/accordion.d.ts.map +1 -0
  230. package/lib/esm/components/accordion/index.d.ts +7 -0
  231. package/lib/esm/components/accordion/index.d.ts.map +1 -0
  232. package/lib/esm/components/accordion/types.d.ts +15 -0
  233. package/lib/esm/components/accordion/types.d.ts.map +1 -0
  234. package/lib/esm/components/collapse/collapse.d.ts +28 -0
  235. package/lib/esm/components/collapse/collapse.d.ts.map +1 -0
  236. package/lib/esm/components/collapse/collapse.js +0 -2
  237. package/lib/esm/components/collapse/collapse.js.map +1 -1
  238. package/lib/esm/components/collapse/index.d.ts +7 -0
  239. package/lib/esm/components/collapse/index.d.ts.map +1 -0
  240. package/lib/esm/components/collapse/types.d.ts +15 -0
  241. package/lib/esm/components/collapse/types.d.ts.map +1 -0
  242. package/lib/esm/components/component.d.ts +44 -0
  243. package/lib/esm/components/component.d.ts.map +1 -0
  244. package/lib/esm/components/component.js +3 -1
  245. package/lib/esm/components/component.js.map +1 -1
  246. package/lib/esm/components/constants.d.ts +6 -0
  247. package/lib/esm/components/constants.d.ts.map +1 -0
  248. package/lib/esm/components/datatable/datatable-checkbox.d.ts +16 -0
  249. package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -0
  250. package/lib/esm/components/datatable/datatable-sort.d.ts +16 -0
  251. package/lib/esm/components/datatable/datatable-sort.d.ts.map +1 -0
  252. package/lib/esm/components/datatable/datatable-sort.js +1 -2
  253. package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
  254. package/lib/esm/components/datatable/datatable.d.ts +339 -0
  255. package/lib/esm/components/datatable/datatable.d.ts.map +1 -0
  256. package/lib/esm/components/datatable/datatable.js +45 -23
  257. package/lib/esm/components/datatable/datatable.js.map +1 -1
  258. package/lib/esm/components/datatable/index.d.ts +7 -0
  259. package/lib/esm/components/datatable/index.d.ts.map +1 -0
  260. package/lib/esm/components/datatable/types.d.ts +166 -0
  261. package/lib/esm/components/datatable/types.d.ts.map +1 -0
  262. package/lib/esm/components/dismiss/dismiss.d.ts +30 -0
  263. package/lib/esm/components/dismiss/dismiss.d.ts.map +1 -0
  264. package/lib/esm/components/dismiss/index.d.ts +7 -0
  265. package/lib/esm/components/dismiss/index.d.ts.map +1 -0
  266. package/lib/esm/components/dismiss/types.d.ts +15 -0
  267. package/lib/esm/components/dismiss/types.d.ts.map +1 -0
  268. package/lib/esm/components/drawer/drawer.d.ts +63 -0
  269. package/lib/esm/components/drawer/drawer.d.ts.map +1 -0
  270. package/lib/esm/components/drawer/drawer.js +21 -9
  271. package/lib/esm/components/drawer/drawer.js.map +1 -1
  272. package/lib/esm/components/drawer/index.d.ts +7 -0
  273. package/lib/esm/components/drawer/index.d.ts.map +1 -0
  274. package/lib/esm/components/drawer/types.d.ts +27 -0
  275. package/lib/esm/components/drawer/types.d.ts.map +1 -0
  276. package/lib/esm/components/dropdown/dropdown.d.ts +71 -0
  277. package/lib/esm/components/dropdown/dropdown.d.ts.map +1 -0
  278. package/lib/esm/components/dropdown/dropdown.js.map +1 -1
  279. package/lib/esm/components/dropdown/index.d.ts +7 -0
  280. package/lib/esm/components/dropdown/index.d.ts.map +1 -0
  281. package/lib/esm/components/dropdown/types.d.ts +27 -0
  282. package/lib/esm/components/dropdown/types.d.ts.map +1 -0
  283. package/lib/esm/components/image-input/image-input.d.ts +42 -0
  284. package/lib/esm/components/image-input/image-input.d.ts.map +1 -0
  285. package/lib/esm/components/image-input/index.d.ts +7 -0
  286. package/lib/esm/components/image-input/index.d.ts.map +1 -0
  287. package/lib/esm/components/image-input/types.d.ts +12 -0
  288. package/lib/esm/components/image-input/types.d.ts.map +1 -0
  289. package/lib/esm/components/modal/index.d.ts +7 -0
  290. package/lib/esm/components/modal/index.d.ts.map +1 -0
  291. package/lib/esm/components/modal/modal.d.ts +45 -0
  292. package/lib/esm/components/modal/modal.d.ts.map +1 -0
  293. package/lib/esm/components/modal/types.d.ts +21 -0
  294. package/lib/esm/components/modal/types.d.ts.map +1 -0
  295. package/lib/esm/components/rating/index.d.ts +7 -0
  296. package/lib/esm/components/rating/index.d.ts.map +1 -0
  297. package/lib/esm/components/rating/index.js +6 -0
  298. package/lib/esm/components/rating/index.js.map +1 -0
  299. package/lib/esm/components/rating/rating.d.ts +31 -0
  300. package/lib/esm/components/rating/rating.d.ts.map +1 -0
  301. package/lib/esm/components/rating/rating.js +236 -0
  302. package/lib/esm/components/rating/rating.js.map +1 -0
  303. package/lib/esm/components/rating/types.d.ts +25 -0
  304. package/lib/esm/components/rating/types.d.ts.map +1 -0
  305. package/lib/esm/components/rating/types.js +6 -0
  306. package/lib/esm/components/rating/types.js.map +1 -0
  307. package/lib/esm/components/reparent/index.d.ts +7 -0
  308. package/lib/esm/components/reparent/index.d.ts.map +1 -0
  309. package/lib/esm/components/reparent/reparent.d.ts +25 -0
  310. package/lib/esm/components/reparent/reparent.d.ts.map +1 -0
  311. package/lib/esm/components/reparent/types.d.ts +13 -0
  312. package/lib/esm/components/reparent/types.d.ts.map +1 -0
  313. package/lib/esm/components/repeater/index.d.ts +7 -0
  314. package/lib/esm/components/repeater/index.d.ts.map +1 -0
  315. package/lib/esm/components/repeater/index.js +6 -0
  316. package/lib/esm/components/repeater/index.js.map +1 -0
  317. package/lib/esm/components/repeater/repeater.d.ts +33 -0
  318. package/lib/esm/components/repeater/repeater.d.ts.map +1 -0
  319. package/lib/esm/components/repeater/repeater.js +170 -0
  320. package/lib/esm/components/repeater/repeater.js.map +1 -0
  321. package/lib/esm/components/repeater/types.d.ts +18 -0
  322. package/lib/esm/components/repeater/types.d.ts.map +1 -0
  323. package/lib/esm/components/repeater/types.js +6 -0
  324. package/lib/esm/components/repeater/types.js.map +1 -0
  325. package/lib/esm/components/scrollable/index.d.ts +7 -0
  326. package/lib/esm/components/scrollable/index.d.ts.map +1 -0
  327. package/lib/esm/components/scrollable/scrollable.d.ts +37 -0
  328. package/lib/esm/components/scrollable/scrollable.d.ts.map +1 -0
  329. package/lib/esm/components/scrollable/types.d.ts +15 -0
  330. package/lib/esm/components/scrollable/types.d.ts.map +1 -0
  331. package/lib/esm/components/scrollspy/index.d.ts +7 -0
  332. package/lib/esm/components/scrollspy/index.d.ts.map +1 -0
  333. package/lib/esm/components/scrollspy/scrollspy.d.ts +35 -0
  334. package/lib/esm/components/scrollspy/scrollspy.d.ts.map +1 -0
  335. package/lib/esm/components/scrollspy/types.d.ts +14 -0
  336. package/lib/esm/components/scrollspy/types.d.ts.map +1 -0
  337. package/lib/esm/components/scrollto/index.d.ts +7 -0
  338. package/lib/esm/components/scrollto/index.d.ts.map +1 -0
  339. package/lib/esm/components/scrollto/scrollto.d.ts +28 -0
  340. package/lib/esm/components/scrollto/scrollto.d.ts.map +1 -0
  341. package/lib/esm/components/scrollto/scrollto.js +0 -2
  342. package/lib/esm/components/scrollto/scrollto.js.map +1 -1
  343. package/lib/esm/components/scrollto/types.d.ts +14 -0
  344. package/lib/esm/components/scrollto/types.d.ts.map +1 -0
  345. package/lib/esm/components/select/combobox.d.ts +52 -0
  346. package/lib/esm/components/select/combobox.d.ts.map +1 -0
  347. package/lib/esm/components/select/combobox.js.map +1 -1
  348. package/lib/esm/components/select/config.d.ts +105 -0
  349. package/lib/esm/components/select/config.d.ts.map +1 -0
  350. package/lib/esm/components/select/dropdown.d.ts +101 -0
  351. package/lib/esm/components/select/dropdown.d.ts.map +1 -0
  352. package/lib/esm/components/select/dropdown.js.map +1 -1
  353. package/lib/esm/components/select/index.d.ts +13 -0
  354. package/lib/esm/components/select/index.d.ts.map +1 -0
  355. package/lib/esm/components/select/option.d.ts +23 -0
  356. package/lib/esm/components/select/option.d.ts.map +1 -0
  357. package/lib/esm/components/select/remote.d.ts +91 -0
  358. package/lib/esm/components/select/remote.d.ts.map +1 -0
  359. package/lib/esm/components/select/remote.js.map +1 -1
  360. package/lib/esm/components/select/search.d.ts +67 -0
  361. package/lib/esm/components/select/search.d.ts.map +1 -0
  362. package/lib/esm/components/select/search.js +9 -5
  363. package/lib/esm/components/select/search.js.map +1 -1
  364. package/lib/esm/components/select/select.d.ts +427 -0
  365. package/lib/esm/components/select/select.d.ts.map +1 -0
  366. package/lib/esm/components/select/select.js +25 -5
  367. package/lib/esm/components/select/select.js.map +1 -1
  368. package/lib/esm/components/select/tags.d.ts +32 -0
  369. package/lib/esm/components/select/tags.d.ts.map +1 -0
  370. package/lib/esm/components/select/tags.js.map +1 -1
  371. package/lib/esm/components/select/templates.d.ts +79 -0
  372. package/lib/esm/components/select/templates.d.ts.map +1 -0
  373. package/lib/esm/components/select/templates.js.map +1 -1
  374. package/lib/esm/components/select/types.d.ts +23 -0
  375. package/lib/esm/components/select/types.d.ts.map +1 -0
  376. package/lib/esm/components/select/utils.d.ts +130 -0
  377. package/lib/esm/components/select/utils.d.ts.map +1 -0
  378. package/lib/esm/components/select/utils.js +10 -0
  379. package/lib/esm/components/select/utils.js.map +1 -1
  380. package/lib/esm/components/stepper/index.d.ts +7 -0
  381. package/lib/esm/components/stepper/index.d.ts.map +1 -0
  382. package/lib/esm/components/stepper/stepper.d.ts +53 -0
  383. package/lib/esm/components/stepper/stepper.d.ts.map +1 -0
  384. package/lib/esm/components/stepper/types.d.ts +12 -0
  385. package/lib/esm/components/stepper/types.d.ts.map +1 -0
  386. package/lib/esm/components/sticky/index.d.ts +7 -0
  387. package/lib/esm/components/sticky/index.d.ts.map +1 -0
  388. package/lib/esm/components/sticky/sticky.d.ts +51 -0
  389. package/lib/esm/components/sticky/sticky.d.ts.map +1 -0
  390. package/lib/esm/components/sticky/sticky.js +104 -24
  391. package/lib/esm/components/sticky/sticky.js.map +1 -1
  392. package/lib/esm/components/sticky/types.d.ts +28 -0
  393. package/lib/esm/components/sticky/types.d.ts.map +1 -0
  394. package/lib/esm/components/tabs/index.d.ts +7 -0
  395. package/lib/esm/components/tabs/index.d.ts.map +1 -0
  396. package/lib/esm/components/tabs/tabs.d.ts +38 -0
  397. package/lib/esm/components/tabs/tabs.d.ts.map +1 -0
  398. package/lib/esm/components/tabs/types.d.ts +12 -0
  399. package/lib/esm/components/tabs/types.d.ts.map +1 -0
  400. package/lib/esm/components/theme-switch/index.d.ts +7 -0
  401. package/lib/esm/components/theme-switch/index.d.ts.map +1 -0
  402. package/lib/esm/components/theme-switch/theme-switch.d.ts +33 -0
  403. package/lib/esm/components/theme-switch/theme-switch.d.ts.map +1 -0
  404. package/lib/esm/components/theme-switch/theme-switch.js +0 -2
  405. package/lib/esm/components/theme-switch/theme-switch.js.map +1 -1
  406. package/lib/esm/components/theme-switch/types.d.ts +13 -0
  407. package/lib/esm/components/theme-switch/types.d.ts.map +1 -0
  408. package/lib/esm/components/toast/index.d.ts +7 -0
  409. package/lib/esm/components/toast/index.d.ts.map +1 -0
  410. package/lib/esm/components/toast/toast.d.ts +76 -0
  411. package/lib/esm/components/toast/toast.d.ts.map +1 -0
  412. package/lib/esm/components/toast/toast.js +1 -2
  413. package/lib/esm/components/toast/toast.js.map +1 -1
  414. package/lib/esm/components/toast/types.d.ts +146 -0
  415. package/lib/esm/components/toast/types.d.ts.map +1 -0
  416. package/lib/esm/components/toggle/index.d.ts +7 -0
  417. package/lib/esm/components/toggle/index.d.ts.map +1 -0
  418. package/lib/esm/components/toggle/toggle.d.ts +31 -0
  419. package/lib/esm/components/toggle/toggle.d.ts.map +1 -0
  420. package/lib/esm/components/toggle/types.d.ts +17 -0
  421. package/lib/esm/components/toggle/types.d.ts.map +1 -0
  422. package/lib/esm/components/toggle-password/index.d.ts +7 -0
  423. package/lib/esm/components/toggle-password/index.d.ts.map +1 -0
  424. package/lib/esm/components/toggle-password/toggle-password.d.ts +32 -0
  425. package/lib/esm/components/toggle-password/toggle-password.d.ts.map +1 -0
  426. package/lib/esm/components/toggle-password/types.d.ts +12 -0
  427. package/lib/esm/components/toggle-password/types.d.ts.map +1 -0
  428. package/lib/esm/components/tooltip/index.d.ts +7 -0
  429. package/lib/esm/components/tooltip/index.d.ts.map +1 -0
  430. package/lib/esm/components/tooltip/tooltip.d.ts +46 -0
  431. package/lib/esm/components/tooltip/tooltip.d.ts.map +1 -0
  432. package/lib/esm/components/tooltip/types.d.ts +26 -0
  433. package/lib/esm/components/tooltip/types.d.ts.map +1 -0
  434. package/lib/esm/helpers/data.d.ts +13 -0
  435. package/lib/esm/helpers/data.d.ts.map +1 -0
  436. package/lib/esm/helpers/dom.d.ts +42 -0
  437. package/lib/esm/helpers/dom.d.ts.map +1 -0
  438. package/lib/esm/helpers/dom.js +0 -2
  439. package/lib/esm/helpers/dom.js.map +1 -1
  440. package/lib/esm/helpers/event-handler.d.ts +14 -0
  441. package/lib/esm/helpers/event-handler.d.ts.map +1 -0
  442. package/lib/esm/helpers/utils.d.ts +25 -0
  443. package/lib/esm/helpers/utils.d.ts.map +1 -0
  444. package/lib/esm/index.d.ts +114 -0
  445. package/lib/esm/index.d.ts.map +1 -0
  446. package/lib/esm/index.js +6 -0
  447. package/lib/esm/index.js.map +1 -1
  448. package/lib/esm/types.d.ts +17 -0
  449. package/lib/esm/types.d.ts.map +1 -0
  450. package/package.json +17 -9
  451. package/skills/ktui-components/SKILL.md +41 -0
  452. package/skills/ktui-theming/SKILL.md +50 -0
  453. package/src/components/collapse/collapse.ts +0 -3
  454. package/src/components/component.ts +5 -5
  455. package/src/components/datatable/__tests__/currency-sort.test.ts +108 -0
  456. package/src/components/datatable/__tests__/multi-row-headers.test.ts +121 -0
  457. package/src/components/datatable/__tests__/pagination-reset.test.ts +13 -5
  458. package/src/components/datatable/__tests__/race-conditions.test.ts +138 -78
  459. package/src/components/datatable/__tests__/setup.ts +9 -4
  460. package/src/components/datatable/datatable-sort.ts +12 -16
  461. package/src/components/datatable/datatable.css +4 -4
  462. package/src/components/datatable/datatable.ts +56 -26
  463. package/src/components/datatable/types.ts +3 -1
  464. package/src/components/drawer/drawer.ts +61 -24
  465. package/src/components/dropdown/dropdown.ts +3 -1
  466. package/src/components/input/input-group.css +15 -5
  467. package/src/components/rating/__tests__/rating.test.ts +234 -0
  468. package/src/components/rating/index.ts +11 -0
  469. package/src/components/rating/rating.css +11 -0
  470. package/src/components/rating/rating.ts +234 -0
  471. package/src/components/rating/types.ts +27 -0
  472. package/src/components/repeater/__tests__/repeater.test.ts +308 -0
  473. package/src/components/repeater/index.ts +7 -0
  474. package/src/components/repeater/repeater.ts +179 -0
  475. package/src/components/repeater/types.ts +19 -0
  476. package/src/components/scrollto/scrollto.ts +0 -3
  477. package/src/components/select/__tests__/ux-behaviors.test.ts +274 -8
  478. package/src/components/select/combobox.ts +0 -1
  479. package/src/components/select/dropdown.ts +0 -2
  480. package/src/components/select/remote.ts +1 -6
  481. package/src/components/select/search.ts +14 -7
  482. package/src/components/select/select.ts +33 -29
  483. package/src/components/select/tags.ts +0 -1
  484. package/src/components/select/templates.ts +8 -8
  485. package/src/components/select/utils.ts +15 -2
  486. package/src/components/sticky/__tests__/sticky.test.ts +205 -0
  487. package/src/components/sticky/sticky.ts +119 -21
  488. package/src/components/sticky/types.ts +3 -0
  489. package/src/components/theme-switch/theme-switch.ts +0 -3
  490. package/src/components/toast/toast.ts +3 -2
  491. package/src/helpers/dom.ts +0 -3
  492. package/src/index.ts +108 -0
  493. package/styles.css +1 -0
  494. package/lib/cjs/components/datatable/__tests__/pagination-reset.test.js +0 -596
  495. package/lib/cjs/components/datatable/__tests__/pagination-reset.test.js.map +0 -1
  496. package/lib/cjs/components/datatable/__tests__/race-conditions.test.js +0 -548
  497. package/lib/cjs/components/datatable/__tests__/race-conditions.test.js.map +0 -1
  498. package/lib/cjs/components/datatable/__tests__/setup.js +0 -63
  499. package/lib/cjs/components/datatable/__tests__/setup.js.map +0 -1
  500. package/lib/esm/components/datatable/__tests__/pagination-reset.test.js +0 -594
  501. package/lib/esm/components/datatable/__tests__/pagination-reset.test.js.map +0 -1
  502. package/lib/esm/components/datatable/__tests__/race-conditions.test.js +0 -546
  503. package/lib/esm/components/datatable/__tests__/race-conditions.test.js.map +0 -1
  504. package/lib/esm/components/datatable/__tests__/setup.js +0 -58
  505. package/lib/esm/components/datatable/__tests__/setup.js.map +0 -1
@@ -156,7 +156,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
156
156
  dropdown: (
157
157
  config: KTSelectConfigInterface & { zindex?: number; content?: string },
158
158
  ) => {
159
- let template = getTemplateStrings(config).dropdown;
159
+ const template = getTemplateStrings(config).dropdown;
160
160
  // If a custom dropdownTemplate is provided, it's responsible for its own content.
161
161
  // Otherwise, the base template is used, and content is appended later.
162
162
  if (config.dropdownTemplate) {
@@ -200,7 +200,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
200
200
  * Renders the load more button for pagination
201
201
  */
202
202
  loadMore: (config: KTSelectConfigInterface): HTMLElement => {
203
- let html = getTemplateStrings(config)
203
+ const html = getTemplateStrings(config)
204
204
  .loadMore // .replace('{{loadMoreText}}', config.loadMoreText || 'Load more...') // Content is no longer in template string
205
205
  .replace('{{class}}', config.loadMoreClass || '');
206
206
  const element = stringToElement(html);
@@ -239,7 +239,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
239
239
  * Renders the display element (trigger) for the select
240
240
  */
241
241
  display: (config: KTSelectConfigInterface): HTMLElement => {
242
- let html = getTemplateStrings(config)
242
+ const html = getTemplateStrings(config)
243
243
  .display.replace('{{tabindex}}', config.disabled ? '-1' : '0')
244
244
  .replace('{{label}}', config.label || config.placeholder || 'Select...')
245
245
  .replace('{{disabled}}', config.disabled ? 'aria-disabled="true"' : '')
@@ -335,7 +335,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
335
335
  * Renders the search input
336
336
  */
337
337
  search: (config: KTSelectConfigInterface): HTMLElement => {
338
- let html = getTemplateStrings(config)
338
+ const html = getTemplateStrings(config)
339
339
  .search.replace(
340
340
  '{{searchPlaceholder}}',
341
341
  config.searchPlaceholder || 'Search...',
@@ -348,7 +348,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
348
348
  * Renders the no results message
349
349
  */
350
350
  searchEmpty: (config: KTSelectConfigInterface): HTMLElement => {
351
- let html = getTemplateStrings(config).searchEmpty.replace(
351
+ const html = getTemplateStrings(config).searchEmpty.replace(
352
352
  '{{class}}',
353
353
  config.searchEmptyClass || '',
354
354
  );
@@ -376,7 +376,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
376
376
  config: KTSelectConfigInterface,
377
377
  loadingMessage: string,
378
378
  ): HTMLElement => {
379
- let html = getTemplateStrings(config).loading.replace(
379
+ const html = getTemplateStrings(config).loading.replace(
380
380
  '{{class}}',
381
381
  config.loadingClass || '',
382
382
  );
@@ -392,7 +392,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
392
392
  option: HTMLOptionElement,
393
393
  config: KTSelectConfigInterface,
394
394
  ): HTMLElement => {
395
- let template = getTemplateStrings(config).tag;
395
+ const template = getTemplateStrings(config).tag;
396
396
  let preparedContent =
397
397
  option.textContent || option.innerText || option.value || ''; // Default content is the option's text
398
398
 
@@ -444,7 +444,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
444
444
  * Renders the placeholder for the select
445
445
  */
446
446
  placeholder: (config: KTSelectConfigInterface): HTMLElement => {
447
- let html = getTemplateStrings(config).placeholder.replace(
447
+ const html = getTemplateStrings(config).placeholder.replace(
448
448
  '{{class}}',
449
449
  config.placeholderClass || '',
450
450
  );
@@ -227,7 +227,7 @@ export class FocusManager {
227
227
  this._focusedOptionIndex === null
228
228
  ? 0
229
229
  : (this._focusedOptionIndex + 1) % options.length;
230
- let startIdx = idx;
230
+ const startIdx = idx;
231
231
  do {
232
232
  const option = options[idx];
233
233
  if (
@@ -255,7 +255,7 @@ export class FocusManager {
255
255
  this._focusedOptionIndex === null
256
256
  ? options.length - 1
257
257
  : (this._focusedOptionIndex - 1 + options.length) % options.length;
258
- let startIdx = idx;
258
+ const startIdx = idx;
259
259
  do {
260
260
  const option = options[idx];
261
261
  if (
@@ -367,6 +367,19 @@ export class FocusManager {
367
367
  return options[this._focusedOptionIndex];
368
368
  }
369
369
 
370
+ // Fallback: DOM may have focus class applied (e.g. by arrow keys from search input)
371
+ // while _focusedOptionIndex is out of sync. Use the option that has the focus class.
372
+ const focusedEl = this._element.querySelector(
373
+ `${this._optionsSelector}.${this._focusClass}`,
374
+ ) as HTMLElement | null;
375
+ if (focusedEl && !focusedEl.classList.contains('hidden') && focusedEl.style.display !== 'none') {
376
+ const idx = options.indexOf(focusedEl);
377
+ if (idx >= 0) {
378
+ this._focusedOptionIndex = idx;
379
+ return focusedEl;
380
+ }
381
+ }
382
+
370
383
  return null;
371
384
  }
372
385
 
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Tests for KTSticky component (PR #107: release delay, active/release classes, debounce)
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
6
+ import * as KTDomModule from '../../../helpers/dom';
7
+ import { KTSticky } from '../sticky';
8
+ import { waitFor } from '../../datatable/__tests__/setup';
9
+
10
+ describe('KTSticky', () => {
11
+ let stickyEl: HTMLElement;
12
+ let wrapper: HTMLElement;
13
+ let scrollTop = 0;
14
+
15
+ beforeEach(() => {
16
+ document.body.innerHTML = '';
17
+ scrollTop = 0;
18
+ vi.spyOn(KTDomModule.default, 'getScrollTop').mockImplementation(() => scrollTop);
19
+ vi.spyOn(KTDomModule.default, 'getViewPort').mockReturnValue({ height: 800, width: 1024 });
20
+
21
+ wrapper = document.createElement('div');
22
+ wrapper.setAttribute('data-kt-sticky-wrapper', 'true');
23
+ wrapper.style.height = '60px';
24
+
25
+ stickyEl = document.createElement('div');
26
+ stickyEl.setAttribute('data-kt-sticky', 'true');
27
+ stickyEl.setAttribute('data-kt-sticky-name', 'test');
28
+ stickyEl.setAttribute('data-kt-sticky-target', 'body');
29
+ stickyEl.setAttribute('data-kt-sticky-offset', '100');
30
+ stickyEl.setAttribute('data-kt-sticky-zindex', '10'); // required for _enable() to set position: fixed
31
+ stickyEl.style.height = '60px';
32
+ wrapper.appendChild(stickyEl);
33
+ document.body.appendChild(wrapper);
34
+ });
35
+
36
+ afterEach(() => {
37
+ vi.useRealTimers();
38
+ vi.restoreAllMocks();
39
+ document.body.innerHTML = '';
40
+ });
41
+
42
+ describe('PR #107: data-kt-sticky-release-delay', () => {
43
+ it('reads releaseDelay from data-kt-sticky-release-delay attribute', () => {
44
+ stickyEl.setAttribute('data-kt-sticky-release-delay', '300');
45
+ const instance = new KTSticky(stickyEl);
46
+ expect(instance.getOption('releaseDelay')).toBe(300);
47
+ instance.dispose();
48
+ });
49
+
50
+ it('delays clearing inline styles when sticky is released (smooth exit)', async () => {
51
+ vi.useFakeTimers();
52
+ stickyEl.setAttribute('data-kt-sticky-release-delay', '250');
53
+ const instance = new KTSticky(stickyEl);
54
+
55
+ // Scroll past offset -> sticky becomes active (sync, no debounce when not active)
56
+ scrollTop = 150;
57
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
58
+ vi.advanceTimersByTime(0);
59
+ expect(stickyEl.classList.contains('active')).toBe(true);
60
+ expect(stickyEl.style.position).toBe('fixed');
61
+
62
+ // Scroll back up -> release (when active, debounce 200ms then _process)
63
+ scrollTop = 50;
64
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
65
+ vi.advanceTimersByTime(250); // debounce 200ms + a bit
66
+ expect(stickyEl.classList.contains('release')).toBe(true);
67
+ expect(stickyEl.style.position).toBe('fixed'); // not cleared yet (delay 250ms)
68
+
69
+ vi.advanceTimersByTime(250); // release delay
70
+ expect(stickyEl.style.position).toBe('');
71
+ expect(stickyEl.style.zIndex).toBe('');
72
+
73
+ vi.useRealTimers();
74
+ instance.dispose();
75
+ });
76
+
77
+ it('with no releaseDelay, inline styles are cleared immediately on release', async () => {
78
+ stickyEl.removeAttribute('data-kt-sticky-release-delay');
79
+ const instance = new KTSticky(stickyEl);
80
+
81
+ scrollTop = 150;
82
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
83
+ await waitFor(50);
84
+ expect(stickyEl.style.position).toBe('fixed');
85
+
86
+ scrollTop = 50;
87
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
88
+ await waitFor(250); // debounce 200ms
89
+ expect(stickyEl.style.position).toBe('');
90
+ instance.dispose();
91
+ });
92
+ });
93
+
94
+ describe('PR #107: data-kt-sticky-active-class and data-kt-sticky-release-class', () => {
95
+ it('applies activeClass when sticky is active and releaseClass when released', async () => {
96
+ stickyEl.setAttribute('data-kt-sticky-active-class', 'sticky-on');
97
+ stickyEl.setAttribute('data-kt-sticky-release-class', 'sticky-off');
98
+ const instance = new KTSticky(stickyEl);
99
+
100
+ scrollTop = 150;
101
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
102
+ await waitFor(50);
103
+ expect(stickyEl.classList.contains('sticky-on')).toBe(true);
104
+ expect(stickyEl.classList.contains('sticky-off')).toBe(false);
105
+
106
+ scrollTop = 50;
107
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
108
+ await waitFor(250);
109
+ expect(stickyEl.classList.contains('sticky-on')).toBe(false);
110
+ expect(stickyEl.classList.contains('sticky-off')).toBe(true);
111
+
112
+ instance.dispose();
113
+ });
114
+
115
+ it('falls back to data-kt-sticky-class when activeClass is not set', async () => {
116
+ stickyEl.setAttribute('data-kt-sticky-class', 'legacy-sticky');
117
+ const instance = new KTSticky(stickyEl);
118
+
119
+ scrollTop = 150;
120
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
121
+ await waitFor(50);
122
+ expect(stickyEl.classList.contains('legacy-sticky')).toBe(true);
123
+ instance.dispose();
124
+ });
125
+ });
126
+
127
+ describe('debounced scroll (no flicker on rapid scroll)', () => {
128
+ it('when active, scroll handler debounces so _process runs after delay', async () => {
129
+ vi.useFakeTimers();
130
+ const instance = new KTSticky(stickyEl);
131
+ scrollTop = 150;
132
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
133
+ vi.advanceTimersByTime(0);
134
+ expect(stickyEl.classList.contains('active')).toBe(true);
135
+
136
+ // Rapid scroll back: multiple scroll events, only one _process after debounce
137
+ scrollTop = 50;
138
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
139
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
140
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
141
+ expect(stickyEl.classList.contains('release')).toBe(false); // not yet, debounce pending
142
+ vi.advanceTimersByTime(250);
143
+ expect(stickyEl.classList.contains('release')).toBe(true);
144
+
145
+ vi.useRealTimers();
146
+ instance.dispose();
147
+ });
148
+ });
149
+
150
+ describe('change event', () => {
151
+ it('fires change event when sticky becomes active and when released', async () => {
152
+ const instance = new KTSticky(stickyEl);
153
+ const changes: { active: boolean }[] = [];
154
+ instance.on('change', (payload: { active: boolean }) => changes.push(payload));
155
+
156
+ scrollTop = 150;
157
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
158
+ await waitFor(50);
159
+ expect(changes).toContainEqual({ active: true });
160
+
161
+ scrollTop = 50;
162
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
163
+ await waitFor(250);
164
+ expect(changes).toContainEqual({ active: false });
165
+
166
+ instance.dispose();
167
+ });
168
+ });
169
+
170
+ describe('dispose', () => {
171
+ it('clears release-delay timeout so _resetStyles does not run after dispose', async () => {
172
+ vi.useFakeTimers();
173
+ stickyEl.setAttribute('data-kt-sticky-release-delay', '500');
174
+ const instance = new KTSticky(stickyEl);
175
+
176
+ scrollTop = 150;
177
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
178
+ vi.advanceTimersByTime(0);
179
+
180
+ scrollTop = 50;
181
+ window.dispatchEvent(new Event('scroll', { bubbles: true }));
182
+ vi.advanceTimersByTime(250);
183
+ expect(stickyEl.style.position).toBe('fixed');
184
+
185
+ instance.dispose();
186
+ vi.advanceTimersByTime(600);
187
+ // If timeout weren't cleared, _resetStyles would have run; element is disposed so we just ensure no throw
188
+ vi.useRealTimers();
189
+ });
190
+ });
191
+
192
+ describe('getInstance / getOrCreateInstance', () => {
193
+ it('getInstance returns null for element without data-kt-sticky', () => {
194
+ stickyEl.removeAttribute('data-kt-sticky');
195
+ expect(KTSticky.getInstance(stickyEl)).toBeNull();
196
+ });
197
+
198
+ it('getOrCreateInstance creates instance and returns it', () => {
199
+ const instance = KTSticky.getOrCreateInstance(stickyEl);
200
+ expect(instance).toBeInstanceOf(KTSticky);
201
+ expect(KTSticky.getInstance(stickyEl)).toBe(instance);
202
+ instance.dispose();
203
+ });
204
+ });
205
+ });
@@ -34,11 +34,17 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
34
34
  reverse: false,
35
35
  release: '',
36
36
  activate: '',
37
+ releaseDelay: 0,
38
+ activeClass: '',
39
+ releaseClass: '',
37
40
  };
38
41
  protected override _config: KTStickyConfigInterface = this._defaultConfig;
39
42
  protected _targetElement: HTMLElement | Document | null = null;
40
43
 
41
44
  protected _attributeRoot: string;
45
+ protected _isScrolling: boolean;
46
+ protected _timeoutState: ReturnType<typeof setTimeout> | null = null;
47
+ protected _scrollTimeout: ReturnType<typeof setTimeout> | null = null;
42
48
  protected _eventTriggerState: boolean;
43
49
  protected _lastScrollTop: number;
44
50
  protected _releaseElement: HTMLElement;
@@ -69,6 +75,9 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
69
75
  );
70
76
  this._wrapperElement = this._element.closest('[data-kt-sticky-wrapper]');
71
77
  this._attributeRoot = `data-kt-sticky-${this._getOption('name')}`;
78
+ this._isScrolling = false;
79
+ this._timeoutState = null;
80
+ this._scrollTimeout = null;
72
81
  this._eventTriggerState = true;
73
82
  this._lastScrollTop = 0;
74
83
 
@@ -110,26 +119,57 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
110
119
 
111
120
  // Store scroll handler reference for cleanup
112
121
  this._scrollHandler = () => {
113
- this._process();
122
+
123
+ this._isScrolling = true;
124
+
125
+ if(this._isActive() === true){
126
+
127
+ this._debounceScroll(() => {
128
+
129
+ this._isScrolling = false;
130
+ this._process();
131
+
132
+ }, 200);
133
+
134
+ }else{
135
+
136
+ this._isScrolling = false;
137
+ this._process();
138
+
139
+ }
140
+
114
141
  };
115
142
 
116
143
  if (this._targetElement) {
117
144
  if (this._targetElement === document) {
118
- window.addEventListener('scroll', this._scrollHandler);
145
+ window.addEventListener('scroll', this._scrollHandler, { passive: true });
119
146
  } else {
120
147
  (this._targetElement as HTMLElement).addEventListener(
121
148
  'scroll',
122
149
  this._scrollHandler,
150
+ { passive: true }
123
151
  );
124
152
  }
125
153
  }
126
154
  }
127
155
 
156
+ protected _debounceScroll(callback: () => void, delay: number = 200): void {
157
+
158
+ if (this._scrollTimeout) {
159
+ clearTimeout(this._scrollTimeout);
160
+ }
161
+
162
+ this._scrollTimeout = setTimeout(() => {
163
+ callback();
164
+ }, delay);
165
+
166
+ }
167
+
128
168
  protected _process(): void {
129
169
  const reverse = this._getOption('reverse');
130
170
  const offset = this._getOffset();
131
171
 
132
- if (offset < 0) {
172
+ if (offset <= 0) {
133
173
  this._disable();
134
174
  return;
135
175
  }
@@ -242,7 +282,6 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
242
282
  const end = this._getOption('end') as string;
243
283
  const height = this._calculateHeight();
244
284
  const zindex = this._getOption('zindex') as string;
245
- const classList = this._getOption('class') as string;
246
285
 
247
286
  if (height + parseInt(top) > KTDom.getViewPort().height) {
248
287
  return false;
@@ -310,16 +349,27 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
310
349
  this._element.style.position = 'fixed';
311
350
  }
312
351
 
313
- if (classList) {
314
- KTDom.addClass(this._element, classList);
352
+ const activeClassList = this._getOption('activeClass') as string;
353
+ if (activeClassList) {
354
+ KTDom.addClass(this._element, activeClassList);
355
+ }else{
356
+ const classList = this._getOption('class') as string;
357
+ if (classList) {
358
+ KTDom.addClass(this._element, classList);
359
+ }
360
+ }
361
+
362
+ const releaseClassList = this._getOption('releaseClass') as string;
363
+ if (releaseClassList) {
364
+ KTDom.removeClass(this._element, releaseClassList);
315
365
  }
316
366
 
317
367
  if (this._wrapperElement) {
318
368
  this._wrapperElement.style.height = `${height}px`;
319
369
  }
320
370
 
321
- this._element.classList.add('active');
322
371
  this._element.classList.remove('release');
372
+ this._element.classList.add('active');
323
373
 
324
374
  return true;
325
375
  }
@@ -327,6 +377,53 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
327
377
  protected _disable(): void {
328
378
  if (!this._element) return;
329
379
 
380
+ if (this._wrapperElement) {
381
+ this._wrapperElement.style.height = '';
382
+ }
383
+
384
+ this._element.classList.remove('active');
385
+ this._element.classList.add('release');
386
+
387
+ const activeClassList = this._getOption('activeClass') as string;
388
+ if (activeClassList) {
389
+ KTDom.removeClass(this._element, activeClassList);
390
+ }else{
391
+ const classList = this._getOption('class') as string;
392
+ if (classList) {
393
+ KTDom.removeClass(this._element, classList);
394
+ }
395
+ }
396
+
397
+ const releaseClassList = this._getOption('releaseClass') as string;
398
+ if (releaseClassList) {
399
+ KTDom.addClass(this._element, releaseClassList);
400
+ }
401
+
402
+ if(this._eventTriggerState === false){
403
+ const releaseDelay = this._getOption('releaseDelay') as number;
404
+ if(releaseDelay && this._timeoutState === null){
405
+ this._timeoutState = setTimeout(() => {
406
+
407
+ if (!this._element){
408
+ return;
409
+ }
410
+
411
+ if (this._isRelease() === true) {
412
+ this._resetStyles();
413
+ }
414
+
415
+ this._timeoutState = null;
416
+
417
+ }, releaseDelay);
418
+ }else{
419
+ this._resetStyles();
420
+ }
421
+ }else{
422
+ this._timeoutState = null;
423
+ }
424
+ }
425
+
426
+ protected _resetStyles = function () {
330
427
  this._element.style.top = '';
331
428
  this._element.style.bottom = '';
332
429
  this._element.style.insetInlineStart = '';
@@ -338,21 +435,11 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
338
435
  this._element.style.right = '';
339
436
  this._element.style.zIndex = '';
340
437
  this._element.style.position = '';
341
-
342
- const classList = this._getOption('class') as string;
343
-
344
- if (this._wrapperElement) {
345
- this._wrapperElement.style.height = '';
346
- }
347
-
348
- if (classList) {
349
- KTDom.removeClass(this._element, classList);
350
- }
351
-
352
- this._element.classList.remove('active');
353
- }
438
+ };
354
439
 
355
440
  protected _update(): void {
441
+ this._timeoutState = null;
442
+ this._eventTriggerState = true;
356
443
  if (this._isActive()) {
357
444
  this._disable();
358
445
  this._enable();
@@ -385,6 +472,10 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
385
472
  return this._element.classList.contains('active');
386
473
  }
387
474
 
475
+ protected _isRelease(): boolean {
476
+ return this._element.classList.contains('release');
477
+ }
478
+
388
479
  public update(): void {
389
480
  this._update();
390
481
  }
@@ -393,6 +484,10 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
393
484
  return this._isActive();
394
485
  }
395
486
 
487
+ public isRelease(): boolean {
488
+ return this._isRelease();
489
+ }
490
+
396
491
  public override dispose(): void {
397
492
  // Remove resize event listener
398
493
  if (this._resizeHandler) {
@@ -415,7 +510,10 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
415
510
 
416
511
  // Clean up state
417
512
  this._disable();
418
- if (this._attributeRoot && document.body.hasAttribute(this._attributeRoot)) {
513
+ if (
514
+ this._attributeRoot &&
515
+ document.body.hasAttribute(this._attributeRoot)
516
+ ) {
419
517
  document.body.removeAttribute(this._attributeRoot);
420
518
  }
421
519
 
@@ -19,6 +19,9 @@ export interface KTStickyConfigInterface {
19
19
  reverse: boolean;
20
20
  release: string;
21
21
  activate: string;
22
+ releaseDelay: number,
23
+ activeClass: string,
24
+ releaseClass: string,
22
25
  }
23
26
 
24
27
  export interface KTStickyInterface {
@@ -3,9 +3,6 @@
3
3
  * Copyright 2025 by Keenthemes Inc
4
4
  */
5
5
 
6
- /* eslint-disable max-len */
7
- /* eslint-disable require-jsdoc */
8
-
9
6
  import KTData from '../../helpers/data';
10
7
  import KTEventHandler from '../../helpers/event-handler';
11
8
  import KTComponent from '../component';
@@ -415,8 +415,9 @@ export class KTToast extends KTComponent implements KTToastInterface {
415
415
  if (options.beep) {
416
416
  try {
417
417
  // Use Web Audio API for a short beep
418
- const ctx = new (window.AudioContext ||
419
- (window as any).webkitAudioContext)();
418
+ const ctx = new (
419
+ window.AudioContext || (window as any).webkitAudioContext
420
+ )();
420
421
  const o = ctx.createOscillator();
421
422
  const g = ctx.createGain();
422
423
  o.type = 'sine';
@@ -3,7 +3,6 @@
3
3
  * Copyright 2025 by Keenthemes Inc
4
4
  */
5
5
 
6
- /* eslint-disable max-len */
7
6
  import KTUtils from './utils';
8
7
  import { KTOffsetType, KTOptionType, KTViewPortType } from '../types';
9
8
 
@@ -130,7 +129,6 @@ const KTDom = {
130
129
  for (
131
130
  element && element !== document.documentElement;
132
131
  (element = element.parentElement as HTMLElement);
133
-
134
132
  ) {
135
133
  if (selector) {
136
134
  if (element.matches(selector)) {
@@ -183,7 +181,6 @@ const KTDom = {
183
181
  return false;
184
182
  }
185
183
 
186
- // eslint-disable-next-line max-len
187
184
  return (
188
185
  getComputedStyle(element).getPropertyValue('visibility') === 'visible'
189
186
  );