@keenthemes/ktui 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/dist/ktui.js +2216 -845
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/dist/styles.css +24 -197
  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/component.d.ts +3 -3
  18. package/lib/cjs/components/component.d.ts.map +1 -1
  19. package/lib/cjs/components/component.js +9 -1
  20. package/lib/cjs/components/component.js.map +1 -1
  21. package/lib/cjs/components/datatable/datatable-checkbox.d.ts +1 -1
  22. package/lib/cjs/components/datatable/datatable-checkbox.d.ts.map +1 -1
  23. package/lib/cjs/components/datatable/datatable-checkbox.js +1 -1
  24. package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
  25. package/lib/cjs/components/datatable/datatable-sort.d.ts +1 -1
  26. package/lib/cjs/components/datatable/datatable-sort.d.ts.map +1 -1
  27. package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
  28. package/lib/cjs/components/datatable/datatable.d.ts +2 -0
  29. package/lib/cjs/components/datatable/datatable.d.ts.map +1 -1
  30. package/lib/cjs/components/datatable/datatable.js +30 -17
  31. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  32. package/lib/cjs/components/datatable/types.d.ts +2 -1
  33. package/lib/cjs/components/datatable/types.d.ts.map +1 -1
  34. package/lib/cjs/components/drawer/drawer.d.ts.map +1 -1
  35. package/lib/cjs/components/drawer/drawer.js +3 -16
  36. package/lib/cjs/components/drawer/drawer.js.map +1 -1
  37. package/lib/cjs/components/dropdown/dropdown.d.ts +1 -1
  38. package/lib/cjs/components/dropdown/dropdown.d.ts.map +1 -1
  39. package/lib/cjs/components/dropdown/dropdown.js +2 -3
  40. package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
  41. package/lib/cjs/components/modal/modal.d.ts.map +1 -1
  42. package/lib/cjs/components/modal/modal.js +19 -13
  43. package/lib/cjs/components/modal/modal.js.map +1 -1
  44. package/lib/cjs/components/pin-input/index.d.ts +3 -0
  45. package/lib/cjs/components/pin-input/index.d.ts.map +1 -0
  46. package/lib/cjs/components/pin-input/index.js +6 -0
  47. package/lib/cjs/components/pin-input/index.js.map +1 -0
  48. package/lib/cjs/components/pin-input/pin-input.d.ts +56 -0
  49. package/lib/cjs/components/pin-input/pin-input.d.ts.map +1 -0
  50. package/lib/cjs/components/pin-input/pin-input.js +455 -0
  51. package/lib/cjs/components/pin-input/pin-input.js.map +1 -0
  52. package/lib/cjs/components/pin-input/types.d.ts +41 -0
  53. package/lib/cjs/components/pin-input/types.d.ts.map +1 -0
  54. package/lib/cjs/components/pin-input/types.js +6 -0
  55. package/lib/cjs/components/pin-input/types.js.map +1 -0
  56. package/lib/cjs/components/rating/rating.d.ts.map +1 -1
  57. package/lib/cjs/components/rating/rating.js.map +1 -1
  58. package/lib/cjs/components/select/combobox.d.ts.map +1 -1
  59. package/lib/cjs/components/select/combobox.js +25 -15
  60. package/lib/cjs/components/select/combobox.js.map +1 -1
  61. package/lib/cjs/components/select/config.d.ts +2 -2
  62. package/lib/cjs/components/select/config.d.ts.map +1 -1
  63. package/lib/cjs/components/select/config.js +10 -9
  64. package/lib/cjs/components/select/config.js.map +1 -1
  65. package/lib/cjs/components/select/dropdown.js.map +1 -1
  66. package/lib/cjs/components/select/option.d.ts +2 -1
  67. package/lib/cjs/components/select/option.d.ts.map +1 -1
  68. package/lib/cjs/components/select/option.js +9 -3
  69. package/lib/cjs/components/select/option.js.map +1 -1
  70. package/lib/cjs/components/select/remote.d.ts +1 -0
  71. package/lib/cjs/components/select/remote.d.ts.map +1 -1
  72. package/lib/cjs/components/select/remote.js +21 -14
  73. package/lib/cjs/components/select/remote.js.map +1 -1
  74. package/lib/cjs/components/select/search.d.ts +1 -1
  75. package/lib/cjs/components/select/search.d.ts.map +1 -1
  76. package/lib/cjs/components/select/search.js +34 -25
  77. package/lib/cjs/components/select/search.js.map +1 -1
  78. package/lib/cjs/components/select/select.d.ts +5 -3
  79. package/lib/cjs/components/select/select.d.ts.map +1 -1
  80. package/lib/cjs/components/select/select.js +31 -31
  81. package/lib/cjs/components/select/select.js.map +1 -1
  82. package/lib/cjs/components/select/tags.d.ts.map +1 -1
  83. package/lib/cjs/components/select/tags.js +22 -13
  84. package/lib/cjs/components/select/tags.js.map +1 -1
  85. package/lib/cjs/components/select/templates.d.ts.map +1 -1
  86. package/lib/cjs/components/select/templates.js +4 -4
  87. package/lib/cjs/components/select/templates.js.map +1 -1
  88. package/lib/cjs/components/select/types.d.ts +1 -1
  89. package/lib/cjs/components/select/types.d.ts.map +1 -1
  90. package/lib/cjs/components/select/utils.d.ts +4 -4
  91. package/lib/cjs/components/select/utils.d.ts.map +1 -1
  92. package/lib/cjs/components/select/utils.js +2 -3
  93. package/lib/cjs/components/select/utils.js.map +1 -1
  94. package/lib/cjs/components/sticky/sticky.d.ts +1 -1
  95. package/lib/cjs/components/sticky/sticky.d.ts.map +1 -1
  96. package/lib/cjs/components/sticky/sticky.js +13 -13
  97. package/lib/cjs/components/sticky/sticky.js.map +1 -1
  98. package/lib/cjs/components/theme-switch/theme-switch.d.ts +3 -0
  99. package/lib/cjs/components/theme-switch/theme-switch.d.ts.map +1 -1
  100. package/lib/cjs/components/theme-switch/theme-switch.js +17 -4
  101. package/lib/cjs/components/theme-switch/theme-switch.js.map +1 -1
  102. package/lib/cjs/components/toast/toast.d.ts.map +1 -1
  103. package/lib/cjs/components/toast/toast.js +17 -9
  104. package/lib/cjs/components/toast/toast.js.map +1 -1
  105. package/lib/cjs/components/toast/types.d.ts +3 -0
  106. package/lib/cjs/components/toast/types.d.ts.map +1 -1
  107. package/lib/cjs/components/toggle/toggle.d.ts +2 -0
  108. package/lib/cjs/components/toggle/toggle.d.ts.map +1 -1
  109. package/lib/cjs/components/toggle/toggle.js +11 -2
  110. package/lib/cjs/components/toggle/toggle.js.map +1 -1
  111. package/lib/cjs/components/toggle-password/toggle-password.d.ts.map +1 -1
  112. package/lib/cjs/components/toggle-password/toggle-password.js.map +1 -1
  113. package/lib/cjs/helpers/dom.d.ts +4 -4
  114. package/lib/cjs/helpers/dom.d.ts.map +1 -1
  115. package/lib/cjs/helpers/dom.js +8 -10
  116. package/lib/cjs/helpers/dom.js.map +1 -1
  117. package/lib/cjs/helpers/event-handler.d.ts +1 -1
  118. package/lib/cjs/helpers/event-handler.d.ts.map +1 -1
  119. package/lib/cjs/helpers/event-handler.js +3 -1
  120. package/lib/cjs/helpers/event-handler.js.map +1 -1
  121. package/lib/cjs/helpers/utils.d.ts +1 -1
  122. package/lib/cjs/helpers/utils.d.ts.map +1 -1
  123. package/lib/cjs/helpers/utils.js +4 -1
  124. package/lib/cjs/helpers/utils.js.map +1 -1
  125. package/lib/cjs/index.d.ts +8 -0
  126. package/lib/cjs/index.d.ts.map +1 -1
  127. package/lib/cjs/index.js +9 -1
  128. package/lib/cjs/index.js.map +1 -1
  129. package/lib/cjs/types.d.ts +1 -1
  130. package/lib/cjs/types.d.ts.map +1 -1
  131. package/lib/esm/components/carousel/carousel.d.ts +102 -0
  132. package/lib/esm/components/carousel/carousel.d.ts.map +1 -0
  133. package/lib/esm/components/carousel/carousel.js +766 -0
  134. package/lib/esm/components/carousel/carousel.js.map +1 -0
  135. package/lib/esm/components/carousel/index.d.ts +7 -0
  136. package/lib/esm/components/carousel/index.d.ts.map +1 -0
  137. package/lib/esm/components/carousel/index.js +6 -0
  138. package/lib/esm/components/carousel/index.js.map +1 -0
  139. package/lib/esm/components/carousel/types.d.ts +36 -0
  140. package/lib/esm/components/carousel/types.d.ts.map +1 -0
  141. package/lib/esm/components/carousel/types.js +6 -0
  142. package/lib/esm/components/carousel/types.js.map +1 -0
  143. package/lib/esm/components/component.d.ts +3 -3
  144. package/lib/esm/components/component.d.ts.map +1 -1
  145. package/lib/esm/components/component.js +9 -1
  146. package/lib/esm/components/component.js.map +1 -1
  147. package/lib/esm/components/datatable/datatable-checkbox.d.ts +1 -1
  148. package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -1
  149. package/lib/esm/components/datatable/datatable-checkbox.js +1 -1
  150. package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
  151. package/lib/esm/components/datatable/datatable-sort.d.ts +1 -1
  152. package/lib/esm/components/datatable/datatable-sort.d.ts.map +1 -1
  153. package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
  154. package/lib/esm/components/datatable/datatable.d.ts +2 -0
  155. package/lib/esm/components/datatable/datatable.d.ts.map +1 -1
  156. package/lib/esm/components/datatable/datatable.js +30 -17
  157. package/lib/esm/components/datatable/datatable.js.map +1 -1
  158. package/lib/esm/components/datatable/types.d.ts +2 -1
  159. package/lib/esm/components/datatable/types.d.ts.map +1 -1
  160. package/lib/esm/components/drawer/drawer.d.ts.map +1 -1
  161. package/lib/esm/components/drawer/drawer.js +3 -16
  162. package/lib/esm/components/drawer/drawer.js.map +1 -1
  163. package/lib/esm/components/dropdown/dropdown.d.ts +1 -1
  164. package/lib/esm/components/dropdown/dropdown.d.ts.map +1 -1
  165. package/lib/esm/components/dropdown/dropdown.js +2 -3
  166. package/lib/esm/components/dropdown/dropdown.js.map +1 -1
  167. package/lib/esm/components/modal/modal.d.ts.map +1 -1
  168. package/lib/esm/components/modal/modal.js +19 -13
  169. package/lib/esm/components/modal/modal.js.map +1 -1
  170. package/lib/esm/components/pin-input/index.d.ts +3 -0
  171. package/lib/esm/components/pin-input/index.d.ts.map +1 -0
  172. package/lib/esm/components/pin-input/index.js +2 -0
  173. package/lib/esm/components/pin-input/index.js.map +1 -0
  174. package/lib/esm/components/pin-input/pin-input.d.ts +56 -0
  175. package/lib/esm/components/pin-input/pin-input.d.ts.map +1 -0
  176. package/lib/esm/components/pin-input/pin-input.js +452 -0
  177. package/lib/esm/components/pin-input/pin-input.js.map +1 -0
  178. package/lib/esm/components/pin-input/types.d.ts +41 -0
  179. package/lib/esm/components/pin-input/types.d.ts.map +1 -0
  180. package/lib/esm/components/pin-input/types.js +5 -0
  181. package/lib/esm/components/pin-input/types.js.map +1 -0
  182. package/lib/esm/components/rating/rating.d.ts.map +1 -1
  183. package/lib/esm/components/rating/rating.js.map +1 -1
  184. package/lib/esm/components/select/combobox.d.ts.map +1 -1
  185. package/lib/esm/components/select/combobox.js +25 -15
  186. package/lib/esm/components/select/combobox.js.map +1 -1
  187. package/lib/esm/components/select/config.d.ts +2 -2
  188. package/lib/esm/components/select/config.d.ts.map +1 -1
  189. package/lib/esm/components/select/config.js +10 -9
  190. package/lib/esm/components/select/config.js.map +1 -1
  191. package/lib/esm/components/select/dropdown.js.map +1 -1
  192. package/lib/esm/components/select/option.d.ts +2 -1
  193. package/lib/esm/components/select/option.d.ts.map +1 -1
  194. package/lib/esm/components/select/option.js +9 -3
  195. package/lib/esm/components/select/option.js.map +1 -1
  196. package/lib/esm/components/select/remote.d.ts +1 -0
  197. package/lib/esm/components/select/remote.d.ts.map +1 -1
  198. package/lib/esm/components/select/remote.js +21 -14
  199. package/lib/esm/components/select/remote.js.map +1 -1
  200. package/lib/esm/components/select/search.d.ts +1 -1
  201. package/lib/esm/components/select/search.d.ts.map +1 -1
  202. package/lib/esm/components/select/search.js +34 -25
  203. package/lib/esm/components/select/search.js.map +1 -1
  204. package/lib/esm/components/select/select.d.ts +5 -3
  205. package/lib/esm/components/select/select.d.ts.map +1 -1
  206. package/lib/esm/components/select/select.js +31 -31
  207. package/lib/esm/components/select/select.js.map +1 -1
  208. package/lib/esm/components/select/tags.d.ts.map +1 -1
  209. package/lib/esm/components/select/tags.js +22 -13
  210. package/lib/esm/components/select/tags.js.map +1 -1
  211. package/lib/esm/components/select/templates.d.ts.map +1 -1
  212. package/lib/esm/components/select/templates.js +4 -4
  213. package/lib/esm/components/select/templates.js.map +1 -1
  214. package/lib/esm/components/select/types.d.ts +1 -1
  215. package/lib/esm/components/select/types.d.ts.map +1 -1
  216. package/lib/esm/components/select/utils.d.ts +4 -4
  217. package/lib/esm/components/select/utils.d.ts.map +1 -1
  218. package/lib/esm/components/select/utils.js +2 -3
  219. package/lib/esm/components/select/utils.js.map +1 -1
  220. package/lib/esm/components/sticky/sticky.d.ts +1 -1
  221. package/lib/esm/components/sticky/sticky.d.ts.map +1 -1
  222. package/lib/esm/components/sticky/sticky.js +13 -13
  223. package/lib/esm/components/sticky/sticky.js.map +1 -1
  224. package/lib/esm/components/theme-switch/theme-switch.d.ts +3 -0
  225. package/lib/esm/components/theme-switch/theme-switch.d.ts.map +1 -1
  226. package/lib/esm/components/theme-switch/theme-switch.js +17 -4
  227. package/lib/esm/components/theme-switch/theme-switch.js.map +1 -1
  228. package/lib/esm/components/toast/toast.d.ts.map +1 -1
  229. package/lib/esm/components/toast/toast.js +17 -9
  230. package/lib/esm/components/toast/toast.js.map +1 -1
  231. package/lib/esm/components/toast/types.d.ts +3 -0
  232. package/lib/esm/components/toast/types.d.ts.map +1 -1
  233. package/lib/esm/components/toggle/toggle.d.ts +2 -0
  234. package/lib/esm/components/toggle/toggle.d.ts.map +1 -1
  235. package/lib/esm/components/toggle/toggle.js +11 -2
  236. package/lib/esm/components/toggle/toggle.js.map +1 -1
  237. package/lib/esm/components/toggle-password/toggle-password.d.ts.map +1 -1
  238. package/lib/esm/components/toggle-password/toggle-password.js.map +1 -1
  239. package/lib/esm/helpers/dom.d.ts +4 -4
  240. package/lib/esm/helpers/dom.d.ts.map +1 -1
  241. package/lib/esm/helpers/dom.js +8 -10
  242. package/lib/esm/helpers/dom.js.map +1 -1
  243. package/lib/esm/helpers/event-handler.d.ts +1 -1
  244. package/lib/esm/helpers/event-handler.d.ts.map +1 -1
  245. package/lib/esm/helpers/event-handler.js +3 -1
  246. package/lib/esm/helpers/event-handler.js.map +1 -1
  247. package/lib/esm/helpers/utils.d.ts +1 -1
  248. package/lib/esm/helpers/utils.d.ts.map +1 -1
  249. package/lib/esm/helpers/utils.js +4 -1
  250. package/lib/esm/helpers/utils.js.map +1 -1
  251. package/lib/esm/index.d.ts +8 -0
  252. package/lib/esm/index.d.ts.map +1 -1
  253. package/lib/esm/index.js +6 -0
  254. package/lib/esm/index.js.map +1 -1
  255. package/lib/esm/types.d.ts +1 -1
  256. package/lib/esm/types.d.ts.map +1 -1
  257. package/package.json +5 -2
  258. package/src/components/carousel/__tests__/carousel.test.ts +326 -0
  259. package/src/components/carousel/carousel.css +42 -0
  260. package/src/components/carousel/carousel.ts +847 -0
  261. package/src/components/carousel/index.ts +11 -0
  262. package/src/components/carousel/types.ts +38 -0
  263. package/src/components/clipboard/__tests__/clipboard.test.ts +4 -4
  264. package/src/components/component.ts +15 -5
  265. package/src/components/datatable/__tests__/currency-sort.test.ts +4 -3
  266. package/src/components/datatable/__tests__/pagination-reset.test.ts +7 -4
  267. package/src/components/datatable/__tests__/setup.ts +1 -1
  268. package/src/components/datatable/datatable-checkbox.ts +6 -4
  269. package/src/components/datatable/datatable-sort.ts +27 -7
  270. package/src/components/datatable/datatable.ts +64 -37
  271. package/src/components/datatable/types.ts +3 -1
  272. package/src/components/drawer/drawer.ts +3 -18
  273. package/src/components/dropdown/dropdown.ts +2 -3
  274. package/src/components/modal/modal.ts +22 -14
  275. package/src/components/pin-input/__tests__/pin-input.test.ts +928 -0
  276. package/src/components/pin-input/index.ts +6 -0
  277. package/src/components/pin-input/pin-input.ts +499 -0
  278. package/src/components/pin-input/types.ts +45 -0
  279. package/src/components/rating/rating.ts +0 -1
  280. package/src/components/repeater/__tests__/repeater.test.ts +5 -5
  281. package/src/components/select/__tests__/ux-behaviors.test.ts +4 -3
  282. package/src/components/select/combobox.ts +23 -16
  283. package/src/components/select/config.ts +15 -14
  284. package/src/components/select/dropdown.ts +1 -1
  285. package/src/components/select/option.ts +14 -4
  286. package/src/components/select/remote.ts +68 -56
  287. package/src/components/select/search.ts +30 -27
  288. package/src/components/select/select.ts +41 -37
  289. package/src/components/select/tags.ts +14 -8
  290. package/src/components/select/templates.ts +11 -6
  291. package/src/components/select/types.ts +1 -1
  292. package/src/components/select/utils.ts +7 -9
  293. package/src/components/sticky/sticky.ts +2 -2
  294. package/src/components/theme-switch/theme-switch.ts +22 -4
  295. package/src/components/toast/toast.ts +34 -21
  296. package/src/components/toast/types.ts +5 -1
  297. package/src/components/toggle/toggle.ts +12 -2
  298. package/src/components/toggle-password/toggle-password.ts +0 -1
  299. package/src/helpers/dom.ts +14 -17
  300. package/src/helpers/event-handler.ts +5 -6
  301. package/src/helpers/utils.ts +5 -2
  302. package/src/index.ts +18 -0
  303. package/src/types.ts +1 -1
  304. package/styles.css +1 -0
@@ -29,7 +29,8 @@ export class KTSelect extends KTComponent {
29
29
  // Core properties
30
30
  protected override readonly _name: string = 'select';
31
31
  protected override readonly _dataOptionPrefix: string = 'kt-'; // Use 'kt-' prefix to support data-kt-select-option attributes
32
- protected override readonly _config: KTSelectConfigInterface;
32
+ protected override _element!: HTMLElement;
33
+ protected override _config: KTSelectConfigInterface;
33
34
  protected override _defaultConfig: KTSelectConfigInterface;
34
35
 
35
36
  // Static global configuration
@@ -81,7 +82,7 @@ export class KTSelect extends KTComponent {
81
82
  this._state = new KTSelectState(this._config);
82
83
  this._config = this._state.getConfig();
83
84
 
84
- (element as any).instance = this;
85
+ (this._element as HTMLElement & { instance?: KTSelect }).instance = this;
85
86
 
86
87
  // Initialize event manager
87
88
  this._eventManager = new EventManager();
@@ -125,8 +126,7 @@ export class KTSelect extends KTComponent {
125
126
  protected override _buildConfig(config: object = {}): void {
126
127
  if (!this._element) return;
127
128
 
128
- // Cast to writable to allow assignment (config is readonly but needs initialization)
129
- (this._config as any) = {
129
+ this._config = {
130
130
  ...this._defaultConfig,
131
131
  ...KTSelect.globalConfig,
132
132
  ...this._getGlobalConfig(),
@@ -143,7 +143,7 @@ export class KTSelect extends KTComponent {
143
143
  */
144
144
  protected override _dispatchEvent(
145
145
  eventType: string,
146
- payload: object = null,
146
+ payload: object | null = null,
147
147
  ): void {
148
148
  // Call parent method to dispatch on element (existing behavior)
149
149
  super._dispatchEvent(eventType, payload);
@@ -179,6 +179,10 @@ export class KTSelect extends KTComponent {
179
179
  }
180
180
  }
181
181
 
182
+ public override getElement(): HTMLElement {
183
+ return this._element;
184
+ }
185
+
182
186
  /**
183
187
  * Initialize remote data fetching
184
188
  */
@@ -461,7 +465,10 @@ export class KTSelect extends KTComponent {
461
465
  optionsContainer.appendChild(
462
466
  defaultTemplates.error({
463
467
  ...this._config,
464
- errorMessage: message,
468
+ errorMessage:
469
+ message ??
470
+ this._config.remoteErrorMessage ??
471
+ 'Failed to load data',
465
472
  }),
466
473
  );
467
474
  break;
@@ -754,7 +761,7 @@ export class KTSelect extends KTComponent {
754
761
  // Create an empty dropdown first (without options) using template
755
762
  const dropdownElement = defaultTemplates.dropdown({
756
763
  ...this._config,
757
- zindex: this._config.dropdownZindex,
764
+ zindex: this._config.dropdownZindex ?? undefined,
758
765
  });
759
766
 
760
767
  // Add search input if needed
@@ -1007,13 +1014,20 @@ export class KTSelect extends KTComponent {
1007
1014
  /**
1008
1015
  * Extract nested property value from object using dot notation
1009
1016
  */
1010
- private _getValueByKey(obj: any, key: string): any {
1017
+ private _getValueByKey(obj: unknown, key: string): unknown {
1011
1018
  if (!key || !obj) return null;
1012
1019
 
1013
1020
  // Use reduce to walk through the object by splitting the key on dots
1014
- const result = key
1015
- .split('.')
1016
- .reduce((o, k) => (o && o[k] !== undefined ? o[k] : null), obj);
1021
+ const result = key.split('.').reduce((o: unknown, k: string) => {
1022
+ if (
1023
+ o &&
1024
+ typeof o === 'object' &&
1025
+ (o as Record<string, unknown>)[k] !== undefined
1026
+ ) {
1027
+ return (o as Record<string, unknown>)[k];
1028
+ }
1029
+ return null;
1030
+ }, obj);
1017
1031
 
1018
1032
  return result;
1019
1033
  }
@@ -1300,7 +1314,7 @@ export class KTSelect extends KTComponent {
1300
1314
  // Sync native select value for FormData support
1301
1315
  this._syncNativeSelectValue();
1302
1316
 
1303
- if (tagsEnabled) {
1317
+ if (this._config.tags && this._tagsModule) {
1304
1318
  // Tags module will render tags if selectedOptions > 0, or clear them if selectedOptions === 0.
1305
1319
  this._tagsModule.updateTagsDisplay(selectedOptions);
1306
1320
  }
@@ -1508,19 +1522,6 @@ export class KTSelect extends KTComponent {
1508
1522
  if (focusedOption) {
1509
1523
  const selectedValue = focusedOption.dataset.value;
1510
1524
 
1511
- // Extract just the title text, not including description
1512
- let selectedText = '';
1513
- const titleElement = focusedOption.querySelector(
1514
- '[data-kt-option-title]',
1515
- );
1516
- if (titleElement) {
1517
- // If it has a structured content with title element
1518
- selectedText = titleElement.textContent?.trim() || '';
1519
- } else {
1520
- // Fallback to the whole text content
1521
- selectedText = focusedOption.textContent?.trim() || '';
1522
- }
1523
-
1524
1525
  // First trigger the selection to ensure state is updated properly
1525
1526
  if (selectedValue) {
1526
1527
  this._selectOption(selectedValue);
@@ -1621,7 +1622,7 @@ export class KTSelect extends KTComponent {
1621
1622
  /**
1622
1623
  * Get the search input element
1623
1624
  */
1624
- public getSearchInput(): HTMLInputElement {
1625
+ public getSearchInput(): HTMLInputElement | null {
1625
1626
  return this._searchInputElement;
1626
1627
  }
1627
1628
 
@@ -1685,7 +1686,7 @@ export class KTSelect extends KTComponent {
1685
1686
  if (option.hasAttribute('style')) {
1686
1687
  const styleAttr = option.getAttribute('style');
1687
1688
 
1688
- if (styleAttr.includes('display:')) {
1689
+ if (styleAttr && styleAttr.includes('display:')) {
1689
1690
  // If style only contains display property, remove the entire attribute
1690
1691
  if (
1691
1692
  styleAttr.trim() === 'display: none;' ||
@@ -1696,7 +1697,7 @@ export class KTSelect extends KTComponent {
1696
1697
  // Otherwise, remove just the display property
1697
1698
  option.setAttribute(
1698
1699
  'style',
1699
- styleAttr?.replace(/display:\s*[^;]+;?/gi, '')?.trim(),
1700
+ styleAttr.replace(/display:\s*[^;]+;?/gi, '').trim(),
1700
1701
  );
1701
1702
  }
1702
1703
  }
@@ -1816,7 +1817,7 @@ export class KTSelect extends KTComponent {
1816
1817
  */
1817
1818
  public override dispose(): void {
1818
1819
  // Clean up event listeners
1819
- this._eventManager.removeAllListeners(null);
1820
+ this._eventManager.removeAllListeners(this._wrapperElement);
1820
1821
 
1821
1822
  // Dispose modules
1822
1823
  if (this._dropdownModule) {
@@ -2464,7 +2465,6 @@ export class KTSelect extends KTComponent {
2464
2465
  }
2465
2466
 
2466
2467
  const isOpen = this._dropdownIsOpen;
2467
- const config = this._config;
2468
2468
  const focusManager = this._focusManager;
2469
2469
  const buffer = this._typeToSearchBuffer;
2470
2470
 
@@ -2588,7 +2588,7 @@ export class KTSelect extends KTComponent {
2588
2588
  }
2589
2589
 
2590
2590
  public renderDisplayTemplateForSelected(selectedValues: string[]): string {
2591
- const optionsConfig = (this._config.optionsConfig as any) || {};
2591
+ const optionsConfig = this._config.optionsConfig || {};
2592
2592
  const displaySeparator = this._config.displaySeparator || ', ';
2593
2593
  const contentArray = Array.from(
2594
2594
  new Set(
@@ -2599,7 +2599,7 @@ export class KTSelect extends KTComponent {
2599
2599
  );
2600
2600
  if (!option) return '';
2601
2601
 
2602
- let displayTemplate = this._config.displayTemplate;
2602
+ let displayTemplate = this._config.displayTemplate || '{{text}}';
2603
2603
  const text = option.getAttribute('data-text') || '';
2604
2604
 
2605
2605
  // Replace all {{varname}} in option.innerHTML with values from _config
@@ -2757,21 +2757,25 @@ export class KTSelect extends KTComponent {
2757
2757
  .getVisibleOptions()
2758
2758
  .filter((opt) => opt.getAttribute('aria-disabled') !== 'true');
2759
2759
 
2760
+ const selectAllButton = this._selectAllButton;
2761
+ const selectAllButtonToggle = this._selectAllButtonToggle;
2762
+ if (!selectAllButton || !selectAllButtonToggle) return;
2763
+
2760
2764
  if (visibleOptions.length === 0) {
2761
- this._selectAllButton.style.display = 'none';
2765
+ selectAllButton.style.display = 'none';
2762
2766
  return;
2763
2767
  }
2764
2768
 
2765
- this._selectAllButton.style.display = '';
2769
+ selectAllButton.style.display = '';
2766
2770
 
2767
2771
  const selectedValues = new Set(this.getSelectedOptions());
2768
2772
  const isAllSelected = visibleOptions.every((opt) =>
2769
2773
  selectedValues.has(opt.dataset.value as string),
2770
2774
  );
2771
2775
 
2772
- this._selectAllButtonToggle.textContent = isAllSelected
2773
- ? this._config.clearAllText
2774
- : this._config.selectAllText;
2776
+ selectAllButtonToggle.textContent = isAllSelected
2777
+ ? (this._config.clearAllText ?? 'Clear all')
2778
+ : (this._config.selectAllText ?? 'Select all');
2775
2779
  }
2776
2780
 
2777
2781
  /**
@@ -14,7 +14,7 @@ import { EventManager } from './utils';
14
14
  export class KTSelectTags {
15
15
  private _select: KTSelect;
16
16
  private _config: KTSelectConfigInterface;
17
- private _valueDisplayElement: HTMLElement;
17
+ private _valueDisplayElement: HTMLElement | null;
18
18
  private _eventManager: EventManager;
19
19
 
20
20
  /**
@@ -32,21 +32,23 @@ export class KTSelectTags {
32
32
  * Renders selected options as tags in the display element
33
33
  */
34
34
  public updateTagsDisplay(selectedOptions: string[]): void {
35
+ if (!this._valueDisplayElement) return;
36
+ const valueDisplayElement = this._valueDisplayElement;
35
37
  // Remove any existing tag elements
36
- const wrapper = this._valueDisplayElement.parentElement;
38
+ const wrapper = valueDisplayElement.parentElement;
37
39
  if (!wrapper) return;
38
40
 
39
41
  // If no options selected, ensure placeholder is shown
40
42
  if (selectedOptions.length === 0) {
41
43
  // Clear any existing content and show placeholder
42
- this._valueDisplayElement.innerHTML = '';
44
+ valueDisplayElement.innerHTML = '';
43
45
  const placeholderEl = defaultTemplates.placeholder(this._config);
44
- this._valueDisplayElement.appendChild(placeholderEl);
46
+ valueDisplayElement.appendChild(placeholderEl);
45
47
  return;
46
48
  }
47
49
 
48
50
  // Clear all existing content before adding tags
49
- this._valueDisplayElement.innerHTML = '';
51
+ valueDisplayElement.innerHTML = '';
50
52
 
51
53
  // Insert each tag before the display element
52
54
  selectedOptions.forEach((optionValue) => {
@@ -62,7 +64,8 @@ export class KTSelectTags {
62
64
  if (!optionElement) {
63
65
  const originalOptions = this._select
64
66
  .getElement()
65
- .querySelectorAll('option');
67
+ ?.querySelectorAll('option');
68
+ if (!originalOptions) return;
66
69
  for (const opt of Array.from(originalOptions)) {
67
70
  if ((opt as HTMLOptionElement).value === optionValue) {
68
71
  optionElement = opt as HTMLOptionElement;
@@ -70,6 +73,7 @@ export class KTSelectTags {
70
73
  }
71
74
  }
72
75
  }
76
+ if (!optionElement) return;
73
77
 
74
78
  const tag = defaultTemplates.tag(optionElement, this._config);
75
79
 
@@ -85,7 +89,7 @@ export class KTSelectTags {
85
89
  }
86
90
 
87
91
  // Insert tag inside the display element
88
- this._valueDisplayElement.appendChild(tag);
92
+ valueDisplayElement.appendChild(tag);
89
93
  });
90
94
  }
91
95
 
@@ -101,6 +105,8 @@ export class KTSelectTags {
101
105
  * Clean up resources used by this module
102
106
  */
103
107
  public destroy(): void {
104
- this._eventManager.removeAllListeners(null);
108
+ if (this._valueDisplayElement) {
109
+ this._eventManager.removeAllListeners(this._valueDisplayElement);
110
+ }
105
111
  }
106
112
  }
@@ -136,7 +136,7 @@ export function getTemplateStrings(
136
136
  ): typeof coreTemplateStrings {
137
137
  const templates =
138
138
  config && typeof config === 'object' && 'templates' in config
139
- ? (config as any).templates
139
+ ? (config as KTSelectConfigInterface).templates
140
140
  : undefined;
141
141
 
142
142
  if (templates) {
@@ -264,7 +264,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
264
264
  config: KTSelectConfigInterface,
265
265
  ): HTMLElement => {
266
266
  const isHtmlOption = option instanceof HTMLOptionElement;
267
- let optionData: Record<string, any>;
267
+ let optionData: Record<string, unknown>;
268
268
 
269
269
  if (isHtmlOption) {
270
270
  // If it's a plain HTMLOptionElement, construct data similarly to how KTSelectOption would
@@ -288,14 +288,14 @@ export const defaultTemplates: KTSelectTemplateInterface = {
288
288
  ).getOptionDataForTemplate();
289
289
  }
290
290
 
291
- let content = optionData?.text?.trim(); // Default content to option's text
291
+ let content = String(optionData?.text || '').trim(); // Default content to option's text
292
292
 
293
293
  if (config.optionTemplate) {
294
294
  // Use the user-provided template string, rendering with the full optionData.
295
295
  // renderTemplateString will replace {{key}} with values from optionData.
296
296
  content = renderTemplateString(config.optionTemplate, optionData);
297
297
  } else {
298
- content = optionData.text || optionData.content; // Prefer explicit text, fallback to content
298
+ content = String(optionData.text || optionData.content || '');
299
299
  }
300
300
 
301
301
  // Use the core option template string as the base structure.
@@ -326,7 +326,7 @@ export const defaultTemplates: KTSelectTemplateInterface = {
326
326
  }
327
327
 
328
328
  // Ensure data-text attribute is set to the original, clean text for searching/filtering
329
- element.setAttribute('data-text', optionData?.text?.trim() || '');
329
+ element.setAttribute('data-text', String(optionData?.text || '').trim());
330
330
 
331
331
  return element;
332
332
  },
@@ -402,7 +402,12 @@ export const defaultTemplates: KTSelectTemplateInterface = {
402
402
 
403
403
  // Replace all {{varname}} in option.innerHTML with values from _config.optionsConfig
404
404
  Object.entries(
405
- (config.optionsConfig as any)?.[optionValue] || {},
405
+ (
406
+ config.optionsConfig as unknown as Record<
407
+ string,
408
+ Record<string, unknown>
409
+ >
410
+ )?.[optionValue] || {},
406
411
  ).forEach(([key, val]) => {
407
412
  if (
408
413
  typeof val === 'string' ||
@@ -15,7 +15,7 @@ export interface KTSelectOption {
15
15
  }
16
16
 
17
17
  export interface KTSelectOptionData {
18
- [key: string]: any;
18
+ [key: string]: unknown;
19
19
  }
20
20
 
21
21
  export interface KTSelectState {
@@ -5,7 +5,6 @@
5
5
 
6
6
  // utils.ts
7
7
 
8
- import { defaultTemplates } from './templates';
9
8
  import { KTSelectConfigInterface } from './config';
10
9
 
11
10
  /**
@@ -99,7 +98,7 @@ export class FocusManager {
99
98
  constructor(
100
99
  element: HTMLElement,
101
100
  optionsSelector: string = '[data-kt-select-option]',
102
- config?: KTSelectConfigInterface,
101
+ _config?: KTSelectConfigInterface,
103
102
  ) {
104
103
  this._element = element;
105
104
  this._optionsSelector = optionsSelector;
@@ -121,8 +120,7 @@ export class FocusManager {
121
120
  const target = e.target as HTMLElement;
122
121
  const optionElement = target.closest(this._optionsSelector);
123
122
 
124
- if (optionElement) {
125
- }
123
+ void optionElement;
126
124
  });
127
125
  }
128
126
 
@@ -442,7 +440,7 @@ export class EventManager {
442
440
  element: HTMLElement,
443
441
  event: string,
444
442
  handler: EventListenerOrEventListenerObject,
445
- context?: any,
443
+ context?: unknown,
446
444
  ): void {
447
445
  if (!element) return;
448
446
 
@@ -514,12 +512,12 @@ export class EventManager {
514
512
  * Debounce function to limit how often a function can be called
515
513
  */
516
514
  export function debounce(
517
- func: (...args: any[]) => void,
515
+ func: (...args: unknown[]) => void,
518
516
  delay: number,
519
- ): (...args: any[]) => void {
517
+ ): (...args: unknown[]) => void {
520
518
  let timeout: ReturnType<typeof setTimeout>;
521
519
 
522
- return function (...args: any[]) {
520
+ return function (...args: unknown[]) {
523
521
  clearTimeout(timeout);
524
522
  timeout = setTimeout(() => func(...args), delay);
525
523
  };
@@ -531,7 +529,7 @@ export function debounce(
531
529
  */
532
530
  export function renderTemplateString(
533
531
  template: string,
534
- data: Record<string, any>,
532
+ data: Record<string, unknown>,
535
533
  ): string {
536
534
  return template.replace(/{{(\w+)}}/g, (_, key) =>
537
535
  data[key] !== undefined && data[key] !== null ? String(data[key]) : '',
@@ -413,7 +413,7 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
413
413
  }
414
414
  }
415
415
 
416
- protected _resetStyles = function () {
416
+ protected _resetStyles(): void {
417
417
  this._element.style.top = '';
418
418
  this._element.style.bottom = '';
419
419
  this._element.style.insetInlineStart = '';
@@ -425,7 +425,7 @@ export class KTSticky extends KTComponent implements KTStickyInterface {
425
425
  this._element.style.right = '';
426
426
  this._element.style.zIndex = '';
427
427
  this._element.style.position = '';
428
- };
428
+ }
429
429
 
430
430
  protected _update(): void {
431
431
  this._timeoutState = null;
@@ -20,12 +20,14 @@ export class KTThemeSwitch
20
20
  extends KTComponent
21
21
  implements KTThemeSwitchInterface
22
22
  {
23
- protected override _name: string = 'theme-swtich';
23
+ protected override _name: string = 'theme-switch';
24
24
  protected override _defaultConfig: KTThemeSwitchConfigInterface = {
25
25
  mode: 'light',
26
26
  };
27
27
  protected _mode: KTThemeSwitchModeType | null = null;
28
28
  protected _currentMode: KTThemeSwitchModeType | null = null;
29
+ protected _themeSwitchToggleEventId: string = '';
30
+ protected _themeSwitchSetEventId: string = '';
29
31
 
30
32
  constructor(
31
33
  element: HTMLElement | HTMLHtmlElement,
@@ -48,7 +50,7 @@ export class KTThemeSwitch
48
50
  protected _handlers(): void {
49
51
  if (!this._element) return;
50
52
 
51
- KTEventHandler.on(
53
+ this._themeSwitchToggleEventId = KTEventHandler.on(
52
54
  document.body,
53
55
  '[data-kt-theme-switch-toggle]',
54
56
  'click',
@@ -57,7 +59,7 @@ export class KTThemeSwitch
57
59
  },
58
60
  );
59
61
 
60
- KTEventHandler.on(
62
+ this._themeSwitchSetEventId = KTEventHandler.on(
61
63
  document.body,
62
64
  '[data-kt-theme-switch-set]',
63
65
  'click',
@@ -141,7 +143,23 @@ export class KTThemeSwitch
141
143
  }
142
144
 
143
145
  public setMode(mode: KTThemeSwitchModeType) {
144
- this.setMode(mode);
146
+ this._setMode(mode);
147
+ }
148
+
149
+ public override dispose(): void {
150
+ if (this._themeSwitchToggleEventId) {
151
+ KTEventHandler.off(
152
+ document.body,
153
+ 'click',
154
+ this._themeSwitchToggleEventId,
155
+ );
156
+ this._themeSwitchToggleEventId = '';
157
+ }
158
+ if (this._themeSwitchSetEventId) {
159
+ KTEventHandler.off(document.body, 'click', this._themeSwitchSetEventId);
160
+ this._themeSwitchSetEventId = '';
161
+ }
162
+ super.dispose();
145
163
  }
146
164
 
147
165
  public static getInstance(): KTThemeSwitch {
@@ -10,6 +10,7 @@ import {
10
10
  KTToastConfig,
11
11
  KTToastInstance,
12
12
  KTToastPosition,
13
+ KTToastClassNames,
13
14
  } from './types';
14
15
 
15
16
  const DEFAULT_CONFIG: KTToastConfig = {
@@ -60,9 +61,9 @@ export class KTToast extends KTComponent implements KTToastInterface {
60
61
  * @returns The toast's HTML markup as a string.
61
62
  */
62
63
  static getContent(options?: KTToastOptions) {
63
- const classNames = {
64
- ...((this.globalConfig.classNames as any) || {}),
65
- ...((options?.classNames as any) || {}),
64
+ const classNames: Partial<KTToastClassNames> = {
65
+ ...(this.globalConfig.classNames || {}),
66
+ ...(options?.classNames || {}),
66
67
  };
67
68
 
68
69
  if (options?.content) {
@@ -237,18 +238,18 @@ export class KTToast extends KTComponent implements KTToastInterface {
237
238
  const position =
238
239
  options.position || this.globalConfig.position || 'top-end';
239
240
 
240
- const classNames = {
241
- ...((this.globalConfig.classNames as any) || {}),
242
- ...((options.classNames as any) || {}),
241
+ const classNames: Partial<KTToastClassNames> = {
242
+ ...(this.globalConfig.classNames || {}),
243
+ ...(options.classNames || {}),
243
244
  };
244
245
 
245
246
  let container = this.containerMap.get(position);
246
247
 
247
248
  if (!container) {
248
249
  container = document.createElement('div');
249
- const classNames = {
250
- ...((this.globalConfig.classNames as any) || {}),
251
- ...((options.classNames as any) || {}),
250
+ const classNames: Partial<KTToastClassNames> = {
251
+ ...(this.globalConfig.classNames || {}),
252
+ ...(options.classNames || {}),
252
253
  };
253
254
  // Fallback to default hardcoded classes if not provided in options or globalConfig
254
255
  container.className =
@@ -260,7 +261,7 @@ export class KTToast extends KTComponent implements KTToastInterface {
260
261
  // Enforce maxToasts
261
262
  if (
262
263
  container.children.length >=
263
- (this.globalConfig.maxToasts || DEFAULT_CONFIG.maxToasts)
264
+ (this.globalConfig.maxToasts ?? DEFAULT_CONFIG.maxToasts ?? 5)
264
265
  ) {
265
266
  const firstToast = container.firstElementChild;
266
267
  if (firstToast) {
@@ -296,7 +297,10 @@ export class KTToast extends KTComponent implements KTToastInterface {
296
297
  };
297
298
 
298
299
  const toast = document.createElement('div');
299
- toast.className = `kt-toast kt-alert ${variantMap[options.variant] || ''} ${appearanceMap[options.appearance] || ''} ${sizeMap[options.size] || ''} ${options.className || ''} ${classNames.toast || ''}`;
300
+ const variantClass = variantMap[options.variant ?? 'info'] || '';
301
+ const appearanceClass = appearanceMap[options.appearance ?? 'solid'] || '';
302
+ const sizeClass = sizeMap[options.size ?? 'md'] || '';
303
+ toast.className = `kt-toast kt-alert ${variantClass} ${appearanceClass} ${sizeClass} ${options.className || ''} ${classNames.toast || ''}`;
300
304
  // ARIA support
301
305
  toast.setAttribute('role', options.role || 'status');
302
306
  toast.setAttribute('aria-live', 'polite');
@@ -392,10 +396,11 @@ export class KTToast extends KTComponent implements KTToastInterface {
392
396
  toast.classList.add(dirClass);
393
397
 
394
398
  // Enforce maxToasts: remove oldest if needed
395
- const maxToasts =
399
+ const maxToasts: number =
396
400
  options.maxToasts ??
397
401
  this.globalConfig.maxToasts ??
398
- DEFAULT_CONFIG.maxToasts;
402
+ DEFAULT_CONFIG.maxToasts ??
403
+ 5;
399
404
  const currentToasts = Array.from(container.children) as HTMLElement[];
400
405
  if (currentToasts.length >= maxToasts && currentToasts.length > 0) {
401
406
  const oldestToast = currentToasts[currentToasts.length - 1];
@@ -415,9 +420,17 @@ export class KTToast extends KTComponent implements KTToastInterface {
415
420
  if (options.beep) {
416
421
  try {
417
422
  // Use Web Audio API for a short beep
418
- const ctx = new (
419
- window.AudioContext || (window as any).webkitAudioContext
420
- )();
423
+ const Ctx =
424
+ window.AudioContext ||
425
+ (
426
+ window as Window & {
427
+ webkitAudioContext?: typeof AudioContext;
428
+ }
429
+ ).webkitAudioContext;
430
+ if (!Ctx) {
431
+ throw new Error('Web Audio API unavailable');
432
+ }
433
+ const ctx = new Ctx();
421
434
  const o = ctx.createOscillator();
422
435
  const g = ctx.createGain();
423
436
  o.type = 'sine';
@@ -430,7 +443,7 @@ export class KTToast extends KTComponent implements KTToastInterface {
430
443
  o.stop();
431
444
  ctx.close();
432
445
  }, 120);
433
- } catch (e) {
446
+ } catch {
434
447
  /* ignore */
435
448
  }
436
449
  }
@@ -442,7 +455,7 @@ export class KTToast extends KTComponent implements KTToastInterface {
442
455
 
443
456
  // Auto-dismiss
444
457
  let timeoutId: number | undefined = undefined;
445
- let remaining = duration;
458
+ let remaining = duration ?? 0;
446
459
  let startTime: number | undefined;
447
460
  let paused = false;
448
461
  let progressEl: HTMLElement | null = null;
@@ -493,7 +506,7 @@ export class KTToast extends KTComponent implements KTToastInterface {
493
506
  if (progressEl) {
494
507
  progressEl.style.transition = 'transform 0ms';
495
508
  progressEl.style.transform = `scaleX(${progressPausedAt})`;
496
- progressEl.offsetHeight; // force reflow
509
+ void progressEl.offsetHeight; // force reflow
497
510
  progressEl.style.transition = `transform ${remaining}ms linear`;
498
511
  progressEl.style.transform = 'scaleX(0)';
499
512
  }
@@ -566,8 +579,8 @@ export class KTToast extends KTComponent implements KTToastInterface {
566
579
  inst?.element.remove();
567
580
  KTToast.toasts.delete(id!);
568
581
  // Try to call onDismiss if available in the toast instance (if stored)
569
- if (typeof (inst as any).options?.onDismiss === 'function') {
570
- (inst as any).options.onDismiss(id);
582
+ if (typeof inst.options?.onDismiss === 'function') {
583
+ inst.options.onDismiss(id);
571
584
  }
572
585
  KTToast._fireEventOnElement(inst.element, 'hidden', { id });
573
586
  KTToast._dispatchEventOnElement(inst.element, 'hidden', { id });
@@ -60,6 +60,7 @@ export interface KTToastClassNames {
60
60
  message?: string; // Message
61
61
  toolbar?: string; // Toolbar
62
62
  actions?: string; // Actions
63
+ progress?: string; // Progress indicator
63
64
  }
64
65
 
65
66
  /**
@@ -93,7 +94,9 @@ export interface KTToastConfigInterface {
93
94
  progress?: boolean;
94
95
  }
95
96
 
96
- export interface KTToastInterface {}
97
+ export interface KTToastInterface {
98
+ dispose(): void;
99
+ }
97
100
 
98
101
  export interface KTToastOptions {
99
102
  /** Custom content for the toast. HTMLElement, function returning HTMLElement, or string (DOM id). If set, replaces all default markup. */
@@ -169,4 +172,5 @@ export interface KTToastInstance {
169
172
  id: string; // Toast unique ID
170
173
  element: HTMLElement; // Toast DOM element
171
174
  timeoutId: number; // Timer ID for auto-dismiss
175
+ options?: KTToastOptions; // Resolved options used to create this toast
172
176
  }
@@ -25,6 +25,7 @@ export class KTToggle extends KTComponent implements KTToggleInterface {
25
25
  };
26
26
  protected override _config: KTToggleConfigInterface = this._defaultConfig;
27
27
  protected _targetElement: HTMLElement;
28
+ protected _clickHandler: (() => void) | null = null;
28
29
 
29
30
  constructor(
30
31
  element: HTMLElement,
@@ -48,9 +49,18 @@ export class KTToggle extends KTComponent implements KTToggleInterface {
48
49
  protected _handlers(): void {
49
50
  if (!this._element) return;
50
51
 
51
- this._element.addEventListener('click', () => {
52
+ this._clickHandler = () => {
52
53
  this._toggle();
53
- });
54
+ };
55
+ this._element.addEventListener('click', this._clickHandler);
56
+ }
57
+
58
+ public override dispose(): void {
59
+ if (this._element && this._clickHandler) {
60
+ this._element.removeEventListener('click', this._clickHandler);
61
+ this._clickHandler = null;
62
+ }
63
+ super.dispose();
54
64
  }
55
65
 
56
66
  private _getTargetElement(): HTMLElement | null {