@keenthemes/ktui 1.0.28 → 1.1.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 (288) hide show
  1. package/README.md +27 -0
  2. package/dist/ktui.js +8780 -6199
  3. package/dist/ktui.min.js +1 -1
  4. package/dist/ktui.min.js.map +1 -1
  5. package/dist/styles.css +2744 -1367
  6. package/lib/cjs/components/alert/alert.js +1025 -0
  7. package/lib/cjs/components/alert/alert.js.map +1 -0
  8. package/lib/cjs/components/alert/index.js +20 -0
  9. package/lib/cjs/components/alert/index.js.map +1 -0
  10. package/lib/cjs/components/alert/templates.js +120 -0
  11. package/lib/cjs/components/alert/templates.js.map +1 -0
  12. package/lib/cjs/components/alert/types.js +7 -0
  13. package/lib/cjs/components/alert/types.js.map +1 -0
  14. package/lib/cjs/components/datepicker/config/config.js +42 -0
  15. package/lib/cjs/components/datepicker/config/config.js.map +1 -0
  16. package/lib/cjs/components/datepicker/config/index.js +24 -0
  17. package/lib/cjs/components/datepicker/config/index.js.map +1 -0
  18. package/lib/cjs/components/datepicker/config/interfaces.js +7 -0
  19. package/lib/cjs/components/datepicker/config/interfaces.js.map +1 -0
  20. package/lib/cjs/components/datepicker/config/types.js +7 -0
  21. package/lib/cjs/components/datepicker/config/types.js.map +1 -0
  22. package/lib/cjs/components/datepicker/core/event-manager.js +135 -0
  23. package/lib/cjs/components/datepicker/core/event-manager.js.map +1 -0
  24. package/lib/cjs/components/datepicker/core/focus-manager.js +167 -0
  25. package/lib/cjs/components/datepicker/core/focus-manager.js.map +1 -0
  26. package/lib/cjs/components/datepicker/core/helpers.js +219 -0
  27. package/lib/cjs/components/datepicker/core/helpers.js.map +1 -0
  28. package/lib/cjs/components/datepicker/core/index.js +25 -0
  29. package/lib/cjs/components/datepicker/core/index.js.map +1 -0
  30. package/lib/cjs/components/datepicker/core/unified-state-manager.js +394 -0
  31. package/lib/cjs/components/datepicker/core/unified-state-manager.js.map +1 -0
  32. package/lib/cjs/components/datepicker/datepicker.js +2066 -763
  33. package/lib/cjs/components/datepicker/datepicker.js.map +1 -1
  34. package/lib/cjs/components/datepicker/index.js +19 -8
  35. package/lib/cjs/components/datepicker/index.js.map +1 -1
  36. package/lib/cjs/components/datepicker/ui/index.js +23 -0
  37. package/lib/cjs/components/datepicker/ui/index.js.map +1 -0
  38. package/lib/cjs/components/datepicker/ui/input/dropdown.js +489 -0
  39. package/lib/cjs/components/datepicker/ui/input/dropdown.js.map +1 -0
  40. package/lib/cjs/components/datepicker/ui/input/index.js +23 -0
  41. package/lib/cjs/components/datepicker/ui/input/index.js.map +1 -0
  42. package/lib/cjs/components/datepicker/ui/input/segmented-input.js +640 -0
  43. package/lib/cjs/components/datepicker/ui/input/segmented-input.js.map +1 -0
  44. package/lib/cjs/components/datepicker/ui/renderers/calendar.js +446 -0
  45. package/lib/cjs/components/datepicker/ui/renderers/calendar.js.map +1 -0
  46. package/lib/cjs/components/datepicker/ui/renderers/footer.js +42 -0
  47. package/lib/cjs/components/datepicker/ui/renderers/footer.js.map +1 -0
  48. package/lib/cjs/components/datepicker/ui/renderers/header.js +32 -0
  49. package/lib/cjs/components/datepicker/ui/renderers/header.js.map +1 -0
  50. package/lib/cjs/components/datepicker/ui/renderers/index.js +25 -0
  51. package/lib/cjs/components/datepicker/ui/renderers/index.js.map +1 -0
  52. package/lib/cjs/components/datepicker/ui/renderers/time-picker.js +384 -0
  53. package/lib/cjs/components/datepicker/ui/renderers/time-picker.js.map +1 -0
  54. package/lib/cjs/components/datepicker/ui/templates/index.js +22 -0
  55. package/lib/cjs/components/datepicker/ui/templates/index.js.map +1 -0
  56. package/lib/cjs/components/datepicker/ui/templates/templates.js +253 -0
  57. package/lib/cjs/components/datepicker/ui/templates/templates.js.map +1 -0
  58. package/lib/cjs/components/datepicker/utils/date-formatters.js +88 -0
  59. package/lib/cjs/components/datepicker/utils/date-formatters.js.map +1 -0
  60. package/lib/cjs/components/datepicker/utils/date-utils.js +194 -0
  61. package/lib/cjs/components/datepicker/utils/date-utils.js.map +1 -0
  62. package/lib/cjs/components/datepicker/utils/index.js +24 -0
  63. package/lib/cjs/components/datepicker/utils/index.js.map +1 -0
  64. package/lib/cjs/components/datepicker/utils/time-utils.js +213 -0
  65. package/lib/cjs/components/datepicker/utils/time-utils.js.map +1 -0
  66. package/lib/cjs/index.js +6 -1
  67. package/lib/cjs/index.js.map +1 -1
  68. package/lib/esm/components/alert/alert.js +1022 -0
  69. package/lib/esm/components/alert/alert.js.map +1 -0
  70. package/lib/esm/components/alert/index.js +4 -0
  71. package/lib/esm/components/alert/index.js.map +1 -0
  72. package/lib/esm/components/alert/templates.js +112 -0
  73. package/lib/esm/components/alert/templates.js.map +1 -0
  74. package/lib/esm/components/alert/types.js +6 -0
  75. package/lib/esm/components/alert/types.js.map +1 -0
  76. package/lib/esm/components/datepicker/config/config.js +39 -0
  77. package/lib/esm/components/datepicker/config/config.js.map +1 -0
  78. package/lib/esm/components/datepicker/config/index.js +8 -0
  79. package/lib/esm/components/datepicker/config/index.js.map +1 -0
  80. package/lib/esm/components/datepicker/config/interfaces.js +6 -0
  81. package/lib/esm/components/datepicker/config/interfaces.js.map +1 -0
  82. package/lib/esm/components/datepicker/config/types.js +6 -0
  83. package/lib/esm/components/datepicker/config/types.js.map +1 -0
  84. package/lib/esm/components/datepicker/core/event-manager.js +133 -0
  85. package/lib/esm/components/datepicker/core/event-manager.js.map +1 -0
  86. package/lib/esm/components/datepicker/core/focus-manager.js +164 -0
  87. package/lib/esm/components/datepicker/core/focus-manager.js.map +1 -0
  88. package/lib/esm/components/datepicker/core/helpers.js +211 -0
  89. package/lib/esm/components/datepicker/core/helpers.js.map +1 -0
  90. package/lib/esm/components/datepicker/core/index.js +9 -0
  91. package/lib/esm/components/datepicker/core/index.js.map +1 -0
  92. package/lib/esm/components/datepicker/core/unified-state-manager.js +391 -0
  93. package/lib/esm/components/datepicker/core/unified-state-manager.js.map +1 -0
  94. package/lib/esm/components/datepicker/datepicker.js +2065 -763
  95. package/lib/esm/components/datepicker/datepicker.js.map +1 -1
  96. package/lib/esm/components/datepicker/index.js +6 -8
  97. package/lib/esm/components/datepicker/index.js.map +1 -1
  98. package/lib/esm/components/datepicker/ui/index.js +7 -0
  99. package/lib/esm/components/datepicker/ui/index.js.map +1 -0
  100. package/lib/esm/components/datepicker/ui/input/dropdown.js +486 -0
  101. package/lib/esm/components/datepicker/ui/input/dropdown.js.map +1 -0
  102. package/lib/esm/components/datepicker/ui/input/index.js +7 -0
  103. package/lib/esm/components/datepicker/ui/input/index.js.map +1 -0
  104. package/lib/esm/components/datepicker/ui/input/segmented-input.js +637 -0
  105. package/lib/esm/components/datepicker/ui/input/segmented-input.js.map +1 -0
  106. package/lib/esm/components/datepicker/ui/renderers/calendar.js +443 -0
  107. package/lib/esm/components/datepicker/ui/renderers/calendar.js.map +1 -0
  108. package/lib/esm/components/datepicker/ui/renderers/footer.js +39 -0
  109. package/lib/esm/components/datepicker/ui/renderers/footer.js.map +1 -0
  110. package/lib/esm/components/datepicker/ui/renderers/header.js +29 -0
  111. package/lib/esm/components/datepicker/ui/renderers/header.js.map +1 -0
  112. package/lib/esm/components/datepicker/ui/renderers/index.js +9 -0
  113. package/lib/esm/components/datepicker/ui/renderers/index.js.map +1 -0
  114. package/lib/esm/components/datepicker/ui/renderers/time-picker.js +381 -0
  115. package/lib/esm/components/datepicker/ui/renderers/time-picker.js.map +1 -0
  116. package/lib/esm/components/datepicker/ui/templates/index.js +6 -0
  117. package/lib/esm/components/datepicker/ui/templates/index.js.map +1 -0
  118. package/lib/esm/components/datepicker/ui/templates/templates.js +242 -0
  119. package/lib/esm/components/datepicker/ui/templates/templates.js.map +1 -0
  120. package/lib/esm/components/datepicker/utils/date-formatters.js +83 -0
  121. package/lib/esm/components/datepicker/utils/date-formatters.js.map +1 -0
  122. package/lib/esm/components/datepicker/utils/date-utils.js +184 -0
  123. package/lib/esm/components/datepicker/utils/date-utils.js.map +1 -0
  124. package/lib/esm/components/datepicker/utils/index.js +8 -0
  125. package/lib/esm/components/datepicker/utils/index.js.map +1 -0
  126. package/lib/esm/components/datepicker/utils/time-utils.js +201 -0
  127. package/lib/esm/components/datepicker/utils/time-utils.js.map +1 -0
  128. package/lib/esm/index.js +4 -0
  129. package/lib/esm/index.js.map +1 -1
  130. package/package.json +22 -3
  131. package/src/components/alert/alert.css +429 -188
  132. package/src/components/alert/alert.ts +990 -0
  133. package/src/components/alert/index.ts +4 -0
  134. package/src/components/alert/templates.ts +110 -0
  135. package/src/components/alert/tests/accessibility/aria-roles.test.ts +19 -0
  136. package/src/components/alert/tests/accessibility/focus-management.test.ts +19 -0
  137. package/src/components/alert/tests/accessibility/keyboard-nav.test.ts +22 -0
  138. package/src/components/alert/tests/actions/confirm-cancel.test.ts +122 -0
  139. package/src/components/alert/tests/actions/input-field.test.ts +180 -0
  140. package/src/components/alert/tests/alert.basic.test.ts +126 -0
  141. package/src/components/alert/tests/alert.config.test.ts +75 -0
  142. package/src/components/alert/tests/alert.templates.test.ts +17 -0
  143. package/src/components/alert/tests/config/attribute-config.test.ts +94 -0
  144. package/src/components/alert/tests/config/json-config.test.ts +119 -0
  145. package/src/components/alert/tests/config/merging.test.ts +89 -0
  146. package/src/components/alert/tests/dismissal/auto-dismiss.test.ts +96 -0
  147. package/src/components/alert/tests/dismissal/escape-key-dismiss.test.ts +105 -0
  148. package/src/components/alert/tests/dismissal/manual-dismiss.test.ts +90 -0
  149. package/src/components/alert/tests/dismissal/outside-click-dismiss.test.ts +91 -0
  150. package/src/components/alert/tests/edge-cases/invalid-config.test.ts +19 -0
  151. package/src/components/alert/tests/edge-cases/multiple-alerts.test.ts +19 -0
  152. package/src/components/alert/tests/rendering/custom-content.test.ts +81 -0
  153. package/src/components/alert/tests/rendering/info-alert.test.ts +84 -0
  154. package/src/components/alert/tests/rendering/success-alert.test.ts +100 -0
  155. package/src/components/alert/tests/templates/default-templates.test.ts +16 -0
  156. package/src/components/alert/tests/templates/user-templates.test.ts +16 -0
  157. package/src/components/alert/types.ts +145 -0
  158. package/src/components/datepicker/__tests__/datepicker-events.test.ts +356 -0
  159. package/src/components/datepicker/__tests__/datepicker-init.test.ts +343 -0
  160. package/src/components/datepicker/__tests__/datepicker-integration.test.ts +435 -0
  161. package/src/components/datepicker/__tests__/datepicker-timezone.test.ts +220 -0
  162. package/src/components/datepicker/__tests__/segmented-input-focus.test.ts +380 -0
  163. package/src/components/datepicker/__tests__/selective-state-updates.test.ts +400 -0
  164. package/src/components/datepicker/__tests__/state-manager.test.ts +421 -0
  165. package/src/components/datepicker/__tests__/time-preservation.test.ts +387 -0
  166. package/src/components/datepicker/config/config.ts +40 -0
  167. package/src/components/datepicker/config/index.ts +8 -0
  168. package/src/components/datepicker/config/interfaces.ts +82 -0
  169. package/src/components/datepicker/config/types.ts +188 -0
  170. package/src/components/datepicker/core/event-manager.ts +159 -0
  171. package/src/components/datepicker/core/focus-manager.ts +201 -0
  172. package/src/components/datepicker/core/helpers.ts +231 -0
  173. package/src/components/datepicker/core/index.ts +9 -0
  174. package/src/components/datepicker/core/unified-state-manager.ts +459 -0
  175. package/src/components/datepicker/datepicker.css +429 -1
  176. package/src/components/datepicker/datepicker.ts +2538 -1277
  177. package/src/components/datepicker/index.ts +6 -8
  178. package/src/components/datepicker/ui/index.ts +7 -0
  179. package/src/components/datepicker/ui/input/dropdown.ts +552 -0
  180. package/src/components/datepicker/ui/input/index.ts +7 -0
  181. package/src/components/datepicker/ui/input/segmented-input.ts +638 -0
  182. package/src/components/datepicker/ui/renderers/__tests__/calendar-optimizations.test.ts +611 -0
  183. package/src/components/datepicker/ui/renderers/calendar.ts +530 -0
  184. package/src/components/datepicker/ui/renderers/footer.ts +43 -0
  185. package/src/components/datepicker/ui/renderers/header.ts +33 -0
  186. package/src/components/datepicker/ui/renderers/index.ts +9 -0
  187. package/src/components/datepicker/ui/renderers/time-picker.ts +438 -0
  188. package/src/components/datepicker/ui/templates/index.ts +6 -0
  189. package/src/components/datepicker/ui/templates/templates.ts +306 -0
  190. package/src/components/datepicker/utils/__tests__/date-formatters.test.ts +160 -0
  191. package/src/components/datepicker/utils/__tests__/date-utils-keys.test.ts +86 -0
  192. package/src/components/datepicker/utils/__tests__/date-utils-timezone.test.ts +215 -0
  193. package/src/components/datepicker/utils/date-formatters.ts +85 -0
  194. package/src/components/datepicker/utils/date-utils.ts +172 -0
  195. package/src/components/datepicker/utils/index.ts +8 -0
  196. package/src/components/datepicker/utils/time-utils.ts +221 -0
  197. package/src/index.ts +7 -1
  198. package/CONTRIBUTING.md +0 -101
  199. package/examples/datatable/checkbox-events-test.html +0 -400
  200. package/examples/datatable/credentials-test.html +0 -423
  201. package/examples/datatable/remote-checkbox-test.html +0 -365
  202. package/examples/datatable/sorting-test.html +0 -258
  203. package/examples/image-input/file-upload-example.html +0 -189
  204. package/examples/modal/persistent.html +0 -205
  205. package/examples/modal/remote-select-dropdown.html +0 -166
  206. package/examples/modal/select-dropdown-container.html +0 -129
  207. package/examples/select/avatar.html +0 -47
  208. package/examples/select/basic-usage.html +0 -39
  209. package/examples/select/country.html +0 -43
  210. package/examples/select/dark-mode.html +0 -93
  211. package/examples/select/description.html +0 -53
  212. package/examples/select/disable-option.html +0 -37
  213. package/examples/select/disable-select.html +0 -35
  214. package/examples/select/dropdowncontainer.html +0 -111
  215. package/examples/select/dynamic-methods.html +0 -273
  216. package/examples/select/formdata-remote.html +0 -161
  217. package/examples/select/global-config.html +0 -81
  218. package/examples/select/icon-multiple.html +0 -50
  219. package/examples/select/icon.html +0 -48
  220. package/examples/select/max-selection.html +0 -38
  221. package/examples/select/modal-container.html +0 -128
  222. package/examples/select/modal-positioning-test.html +0 -338
  223. package/examples/select/modal.html +0 -80
  224. package/examples/select/multiple.html +0 -40
  225. package/examples/select/native-selected.html +0 -64
  226. package/examples/select/placeholder.html +0 -40
  227. package/examples/select/remote-data-preselected.html +0 -283
  228. package/examples/select/remote-data.html +0 -38
  229. package/examples/select/search.html +0 -57
  230. package/examples/select/sizes.html +0 -94
  231. package/examples/select/tags-enhanced.html +0 -86
  232. package/examples/select/tags-icons.html +0 -57
  233. package/examples/select/template-customization.html +0 -61
  234. package/examples/sticky/README.md +0 -158
  235. package/examples/sticky/debug-sticky.html +0 -144
  236. package/examples/sticky/test-runner.html +0 -175
  237. package/examples/sticky/test-sticky-logic.js +0 -369
  238. package/examples/sticky/test-sticky-positioning.html +0 -386
  239. package/examples/toast/example.html +0 -479
  240. package/lib/cjs/components/datepicker/calendar.js +0 -1061
  241. package/lib/cjs/components/datepicker/calendar.js.map +0 -1
  242. package/lib/cjs/components/datepicker/config.js +0 -332
  243. package/lib/cjs/components/datepicker/config.js.map +0 -1
  244. package/lib/cjs/components/datepicker/dropdown.js +0 -635
  245. package/lib/cjs/components/datepicker/dropdown.js.map +0 -1
  246. package/lib/cjs/components/datepicker/events.js +0 -129
  247. package/lib/cjs/components/datepicker/events.js.map +0 -1
  248. package/lib/cjs/components/datepicker/keyboard.js +0 -536
  249. package/lib/cjs/components/datepicker/keyboard.js.map +0 -1
  250. package/lib/cjs/components/datepicker/locales.js +0 -78
  251. package/lib/cjs/components/datepicker/locales.js.map +0 -1
  252. package/lib/cjs/components/datepicker/templates.js +0 -403
  253. package/lib/cjs/components/datepicker/templates.js.map +0 -1
  254. package/lib/cjs/components/datepicker/types.js +0 -23
  255. package/lib/cjs/components/datepicker/types.js.map +0 -1
  256. package/lib/cjs/components/datepicker/utils.js +0 -524
  257. package/lib/cjs/components/datepicker/utils.js.map +0 -1
  258. package/lib/esm/components/datepicker/calendar.js +0 -1058
  259. package/lib/esm/components/datepicker/calendar.js.map +0 -1
  260. package/lib/esm/components/datepicker/config.js +0 -329
  261. package/lib/esm/components/datepicker/config.js.map +0 -1
  262. package/lib/esm/components/datepicker/dropdown.js +0 -632
  263. package/lib/esm/components/datepicker/dropdown.js.map +0 -1
  264. package/lib/esm/components/datepicker/events.js +0 -126
  265. package/lib/esm/components/datepicker/events.js.map +0 -1
  266. package/lib/esm/components/datepicker/keyboard.js +0 -533
  267. package/lib/esm/components/datepicker/keyboard.js.map +0 -1
  268. package/lib/esm/components/datepicker/locales.js +0 -74
  269. package/lib/esm/components/datepicker/locales.js.map +0 -1
  270. package/lib/esm/components/datepicker/templates.js +0 -390
  271. package/lib/esm/components/datepicker/templates.js.map +0 -1
  272. package/lib/esm/components/datepicker/types.js +0 -20
  273. package/lib/esm/components/datepicker/types.js.map +0 -1
  274. package/lib/esm/components/datepicker/utils.js +0 -508
  275. package/lib/esm/components/datepicker/utils.js.map +0 -1
  276. package/prettier.config.js +0 -9
  277. package/src/components/datepicker/calendar.ts +0 -1397
  278. package/src/components/datepicker/config.ts +0 -368
  279. package/src/components/datepicker/dropdown.ts +0 -757
  280. package/src/components/datepicker/events.ts +0 -149
  281. package/src/components/datepicker/keyboard.ts +0 -646
  282. package/src/components/datepicker/locales.ts +0 -80
  283. package/src/components/datepicker/templates.ts +0 -792
  284. package/src/components/datepicker/types.ts +0 -154
  285. package/src/components/datepicker/utils.ts +0 -631
  286. package/src/components/select/variants.css +0 -4
  287. package/tsconfig.json +0 -17
  288. package/webpack.config.js +0 -118
@@ -0,0 +1,1025 @@
1
+ "use strict";
2
+ /*
3
+ * alert.ts - Main entry point for KTAlert (modular alert/dialog component)
4
+ *
5
+ * Provides a modular, extensible alert/dialog system for notifications, confirmations, and custom content.
6
+ * Follows the KTDatepicker pattern: extends KTComponent, uses a template system, and supports full customization.
7
+ *
8
+ * All UI fragments are rendered via dedicated methods and customizable via a one-level config/template system.
9
+ *
10
+ * Copyright 2025 by Keenthemes Inc
11
+ */
12
+ var __extends = (this && this.__extends) || (function () {
13
+ var extendStatics = function (d, b) {
14
+ extendStatics = Object.setPrototypeOf ||
15
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
16
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
17
+ return extendStatics(d, b);
18
+ };
19
+ return function (d, b) {
20
+ if (typeof b !== "function" && b !== null)
21
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
22
+ extendStatics(d, b);
23
+ function __() { this.constructor = d; }
24
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
25
+ };
26
+ })();
27
+ var __assign = (this && this.__assign) || function () {
28
+ __assign = Object.assign || function(t) {
29
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
30
+ s = arguments[i];
31
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
32
+ t[p] = s[p];
33
+ }
34
+ return t;
35
+ };
36
+ return __assign.apply(this, arguments);
37
+ };
38
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
39
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
40
+ return new (P || (P = Promise))(function (resolve, reject) {
41
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
42
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
43
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
44
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
45
+ });
46
+ };
47
+ var __generator = (this && this.__generator) || function (thisArg, body) {
48
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
49
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
50
+ function verb(n) { return function (v) { return step([n, v]); }; }
51
+ function step(op) {
52
+ if (f) throw new TypeError("Generator is already executing.");
53
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
54
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
55
+ if (y = 0, t) op = [op[0] & 2, t.value];
56
+ switch (op[0]) {
57
+ case 0: case 1: t = op; break;
58
+ case 4: _.label++; return { value: op[1], done: false };
59
+ case 5: _.label++; y = op[1]; op = [0]; continue;
60
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
61
+ default:
62
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
63
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
64
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
65
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
66
+ if (t[2]) _.ops.pop();
67
+ _.trys.pop(); continue;
68
+ }
69
+ op = body.call(thisArg, _);
70
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
71
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
72
+ }
73
+ };
74
+ Object.defineProperty(exports, "__esModule", { value: true });
75
+ exports.KTAlert = void 0;
76
+ var component_1 = require("../component");
77
+ var templates_1 = require("./templates");
78
+ /**
79
+ * Default configuration for KTAlert
80
+ */
81
+ var defaultConfig = {
82
+ type: 'info',
83
+ title: '',
84
+ message: '',
85
+ icon: undefined, // success, error, warning, info, question, or custom HTML
86
+ position: 'center',
87
+ dismissible: false,
88
+ modal: false,
89
+ input: false,
90
+ inputPlaceholder: '',
91
+ inputValue: '',
92
+ inputType: 'text',
93
+ inputLabel: '',
94
+ inputAttributes: {},
95
+ customContent: '',
96
+ confirmText: 'OK',
97
+ cancelText: 'Cancel',
98
+ showConfirmButton: true,
99
+ showCancelButton: false,
100
+ showCloseButton: true,
101
+ timer: undefined,
102
+ allowOutsideClick: true,
103
+ allowEscapeKey: true,
104
+ focusConfirm: true,
105
+ showLoaderOnConfirm: false,
106
+ customClass: '',
107
+ loaderHtml: '',
108
+ };
109
+ /**
110
+ * KTAlert
111
+ *
112
+ * Modular alert/dialog component for notifications, confirmations, and custom content.
113
+ *
114
+ * @class
115
+ * @extends KTComponent
116
+ */
117
+ var KTAlert = /** @class */ (function (_super) {
118
+ __extends(KTAlert, _super);
119
+ /**
120
+ * Constructor: Initializes the alert component (matches KTDatepicker pattern)
121
+ * @param element - The root element for the alert
122
+ * @param config - Optional user config
123
+ */
124
+ function KTAlert(element, config) {
125
+ var _this = _super.call(this) || this;
126
+ /**
127
+ * Component name for data attributes and config
128
+ * @protected
129
+ * @type {string}
130
+ */
131
+ _this._name = 'alert';
132
+ /**
133
+ * User-provided template overrides
134
+ * @private
135
+ * @type {Record<string, string | ((data: any) => string)>}
136
+ */
137
+ _this._userTemplates = {};
138
+ /**
139
+ * Timer ID for auto-dismiss
140
+ * @private
141
+ * @type {ReturnType<typeof setTimeout> | null}
142
+ */
143
+ _this._timerId = null;
144
+ _this._init(element);
145
+ _this._buildConfig(config);
146
+ _this._templateSet = (0, templates_1.getTemplateStrings)(_this._config);
147
+ _this._state = {
148
+ isOpen: true,
149
+ isModal: !!_this._config.modal,
150
+ isDismissed: false,
151
+ inputValue: _this._config.inputValue || ''
152
+ };
153
+ _this._render();
154
+ // Auto-dismiss logic: start timer if timer is set in config
155
+ if (typeof _this._config.timer === 'number' && _this._config.timer > 0) {
156
+ _this._timerId = setTimeout(function () {
157
+ if (!_this._state.isDismissed) {
158
+ _this._state.isDismissed = true;
159
+ _this._fireEvent('dismiss', { reason: 'timer' });
160
+ _this._element.innerHTML = '';
161
+ }
162
+ }, _this._config.timer);
163
+ }
164
+ return _this;
165
+ }
166
+ /**
167
+ * Initialize the component (placeholder)
168
+ * @param {HTMLElement} element - The root element for the alert
169
+ * @protected
170
+ */
171
+ KTAlert.prototype._init = function (element) {
172
+ _super.prototype._init.call(this, element);
173
+ // To be implemented: config merging, template setup, event binding
174
+ };
175
+ /**
176
+ * Build the component config by merging defaults, global, data attributes, and user config
177
+ * @param {KTAlertConfig} [config] - Optional user config
178
+ * @protected
179
+ */
180
+ KTAlert.prototype._buildConfig = function (config) {
181
+ if (!this._element)
182
+ return;
183
+ // Merge order: defaultConfig < globalConfig < data attributes < JSON config < user config
184
+ var globalConfig = this._getGlobalConfig();
185
+ // Parse data-kt-alert-* attributes
186
+ var dataAttrs = {};
187
+ Array.from(this._element.attributes).forEach(function (attr) {
188
+ if (attr.name.startsWith('data-kt-alert-') && attr.name !== 'data-kt-alert-config') {
189
+ // Convert kebab-case to camelCase
190
+ var key = attr.name
191
+ .replace('data-kt-alert-', '')
192
+ .replace(/-([a-z])/g, function (_, c) { return c.toUpperCase(); });
193
+ var value = attr.value;
194
+ // Parse booleans and numbers for known config keys
195
+ if ([
196
+ 'dismissible', 'modal', 'input', 'showConfirmButton', 'showCancelButton', 'showCloseButton',
197
+ 'allowOutsideClick', 'allowEscapeKey', 'focusConfirm', 'showLoaderOnConfirm'
198
+ ].includes(key)) {
199
+ value = value === 'true';
200
+ }
201
+ else if (['timer'].includes(key)) {
202
+ value = Number(value);
203
+ }
204
+ else if (['inputAttributes'].includes(key)) {
205
+ try {
206
+ value = JSON.parse(value);
207
+ }
208
+ catch (_a) {
209
+ value = {};
210
+ }
211
+ }
212
+ dataAttrs[key] = value;
213
+ }
214
+ });
215
+ // JSON config (data-kt-alert-config)
216
+ var jsonConfig = {};
217
+ var jsonAttr = this._element.getAttribute('data-kt-alert-config');
218
+ if (jsonAttr) {
219
+ try {
220
+ jsonConfig = JSON.parse(jsonAttr);
221
+ }
222
+ catch (e) {
223
+ // Invalid JSON, ignore
224
+ }
225
+ }
226
+ // Merge all config sources
227
+ var mergedConfig = __assign(__assign(__assign(__assign(__assign({}, defaultConfig), globalConfig), dataAttrs), jsonConfig), (config || {}));
228
+ // Apply per-type theming if present
229
+ if (mergedConfig.theme && mergedConfig.type && mergedConfig.theme[mergedConfig.type]) {
230
+ var themeOverrides = mergedConfig.theme[mergedConfig.type];
231
+ mergedConfig = __assign(__assign(__assign({}, mergedConfig), themeOverrides), {
232
+ // Use custom class templates if provided
233
+ templates: __assign(__assign({}, (mergedConfig.templates || {})), { confirmButton: themeOverrides.confirmButtonClass ? templates_1.coreTemplateStrings.confirmButtonCustomClass : undefined, cancelButton: themeOverrides.cancelButtonClass ? templates_1.coreTemplateStrings.cancelButtonCustomClass : undefined }) });
234
+ }
235
+ this._config = mergedConfig;
236
+ };
237
+ /**
238
+ * Render the alert UI by composing all fragments using templates and config
239
+ * Adds ARIA roles and keyboard navigation for accessibility
240
+ * @private
241
+ */
242
+ KTAlert.prototype._render = function () {
243
+ if (!this._element)
244
+ return;
245
+ this._templateSet = (0, templates_1.getTemplateStrings)(this._config);
246
+ // Render fragments
247
+ var icon = this._renderIcon();
248
+ var title = this._renderTitle();
249
+ var message = this._renderMessage();
250
+ var input = this._renderInput();
251
+ var customContent = this._renderCustomContent();
252
+ var confirmButton = this._renderConfirmButton();
253
+ var cancelButton = this._renderCancelButton();
254
+ var actions = this._renderActions(confirmButton, cancelButton);
255
+ var closeButton = this._renderCloseButton();
256
+ // Compose content
257
+ var content = [icon, title, message, input, customContent, actions, closeButton].join('');
258
+ // Render container
259
+ var containerTpl = this._templateSet.container;
260
+ var containerHtml;
261
+ if ((0, templates_1.isTemplateFunction)(containerTpl)) {
262
+ containerHtml = containerTpl(__assign(__assign({}, this._config), { content: content }));
263
+ }
264
+ else if (typeof containerTpl === 'string') {
265
+ containerHtml = (0, templates_1.renderTemplateString)(containerTpl, __assign(__assign({}, this._config), { content: content }));
266
+ }
267
+ else {
268
+ // Use default container template
269
+ var defaultContainer = templates_1.coreTemplateStrings.container;
270
+ if ((0, templates_1.isTemplateFunction)(defaultContainer)) {
271
+ containerHtml = defaultContainer(__assign(__assign({}, this._config), { content: content }));
272
+ }
273
+ else if (typeof defaultContainer === 'string') {
274
+ containerHtml = (0, templates_1.renderTemplateString)(defaultContainer, __assign(__assign({}, this._config), { content: content }));
275
+ }
276
+ else {
277
+ containerHtml = "<div>".concat(content, "</div>");
278
+ }
279
+ }
280
+ // Create DOM node
281
+ var temp = document.createElement('div');
282
+ temp.innerHTML = containerHtml;
283
+ this._container = temp.firstElementChild;
284
+ // Add custom class if set
285
+ if (this._config.customClass) {
286
+ this._container.classList.add(this._config.customClass);
287
+ }
288
+ // Set ARIA attributes for accessibility
289
+ this._container.setAttribute('role', this._config.modal ? 'alertdialog' : 'alert');
290
+ this._container.setAttribute('aria-modal', this._config.modal ? 'true' : 'false');
291
+ this._container.setAttribute('aria-labelledby', 'kt-alert-title');
292
+ this._container.setAttribute('aria-describedby', 'kt-alert-message');
293
+ // Replace or append to element
294
+ this._element.innerHTML = '';
295
+ this._element.appendChild(this._container);
296
+ // Focus first interactive element
297
+ this._focusFirstInteractive();
298
+ // Bind event listeners
299
+ this._bindEvents();
300
+ // Bind keyboard navigation
301
+ this._bindKeyboardNav();
302
+ };
303
+ /**
304
+ * Focus the first interactive element (input, confirm, cancel, close)
305
+ * @private
306
+ */
307
+ KTAlert.prototype._focusFirstInteractive = function () {
308
+ if (!this._container)
309
+ return;
310
+ // Auto-focus input if configured and input exists
311
+ if (this._config.inputAutoFocus && this._config.input) {
312
+ var inputElement = this._container.querySelector('[data-kt-alert-input]');
313
+ if (inputElement) {
314
+ inputElement.focus();
315
+ return;
316
+ }
317
+ }
318
+ // Fallback to first interactive element
319
+ var first = this._container.querySelector('[data-kt-alert-input], [data-kt-alert-confirm], [data-kt-alert-cancel], [data-kt-alert-close]');
320
+ if (first)
321
+ first.focus();
322
+ };
323
+ /**
324
+ * Keyboard navigation: focus trap, Escape closes, Enter triggers confirm
325
+ * @private
326
+ */
327
+ KTAlert.prototype._bindKeyboardNav = function () {
328
+ var _this = this;
329
+ if (!this._container)
330
+ return;
331
+ var focusable = Array.from(this._container.querySelectorAll('[tabindex="0"]'));
332
+ if (focusable.length === 0)
333
+ return;
334
+ var current = 0;
335
+ // Focus trap for modal
336
+ if (this._config.modal) {
337
+ this._container.addEventListener('keydown', function (e) {
338
+ if (e.key === 'Tab') {
339
+ e.preventDefault();
340
+ if (e.shiftKey) {
341
+ current = (current - 1 + focusable.length) % focusable.length;
342
+ }
343
+ else {
344
+ current = (current + 1) % focusable.length;
345
+ }
346
+ focusable[current].focus();
347
+ }
348
+ });
349
+ }
350
+ // Escape closes alert if dismissible or modal
351
+ this._container.addEventListener('keydown', function (e) {
352
+ if (e.key === 'Escape' && (_this._config.dismissible || _this._config.modal)) {
353
+ _this._clearTimer();
354
+ _this._state.isDismissed = true;
355
+ _this._fireEvent('dismiss', {});
356
+ _this._element.innerHTML = '';
357
+ }
358
+ // Enter triggers confirm if present
359
+ if (e.key === 'Enter') {
360
+ var confirmBtn = _this._container.querySelector('[data-kt-alert-confirm]');
361
+ if (confirmBtn) {
362
+ confirmBtn.click();
363
+ }
364
+ }
365
+ });
366
+ };
367
+ /** Render icon fragment */
368
+ KTAlert.prototype._renderIcon = function () {
369
+ if (!this._config.icon || !this._templateSet.icon)
370
+ return '';
371
+ var iconVal = this._config.icon;
372
+ var tpl = this._templateSet.icon;
373
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
374
+ return tpl(__assign(__assign({}, this._config), { icon: iconVal }));
375
+ }
376
+ else if (typeof tpl === 'string') {
377
+ return (0, templates_1.renderTemplateString)(tpl, __assign(__assign({}, this._config), { icon: iconVal }));
378
+ }
379
+ return '';
380
+ };
381
+ /** Render title fragment */
382
+ KTAlert.prototype._renderTitle = function () {
383
+ if (!this._templateSet.title)
384
+ return '';
385
+ var titleVal = this._config.title || '';
386
+ var tpl = this._templateSet.title;
387
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
388
+ return tpl(__assign(__assign({}, this._config), { title: titleVal }));
389
+ }
390
+ else if (typeof tpl === 'string') {
391
+ return (0, templates_1.renderTemplateString)(tpl, __assign(__assign({}, this._config), { title: titleVal }));
392
+ }
393
+ return '';
394
+ };
395
+ /** Render message fragment */
396
+ KTAlert.prototype._renderMessage = function () {
397
+ if (!this._templateSet.message)
398
+ return '';
399
+ var messageVal = this._config.message || '';
400
+ var tpl = this._templateSet.message;
401
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
402
+ return tpl(__assign(__assign({}, this._config), { message: messageVal }));
403
+ }
404
+ else if (typeof tpl === 'string') {
405
+ return (0, templates_1.renderTemplateString)(tpl, __assign(__assign({}, this._config), { message: messageVal }));
406
+ }
407
+ return '';
408
+ };
409
+ /** Render input fragment */
410
+ KTAlert.prototype._renderInput = function () {
411
+ if (!this._config.input)
412
+ return '';
413
+ var inputType = this._config.inputType || 'text';
414
+ var inputPlaceholder = this._config.inputPlaceholder || '';
415
+ var inputValue = this._config.inputValue || '';
416
+ var inputLabel = this._config.inputLabel || '';
417
+ var attrs = this._config.inputAttributes
418
+ ? Object.entries(this._config.inputAttributes).map(function (_a) {
419
+ var k = _a[0], v = _a[1];
420
+ return "".concat(k, "=\"").concat(v, "\"");
421
+ }).join(' ')
422
+ : '';
423
+ var options = this._config.inputOptions || [];
424
+ var tplKey = 'inputText';
425
+ var optionsHtml = '';
426
+ // Set template key and render options if needed
427
+ switch (inputType) {
428
+ case 'textarea':
429
+ tplKey = 'inputTextarea';
430
+ break;
431
+ case 'select':
432
+ tplKey = 'inputSelect';
433
+ if (options.length > 0) {
434
+ optionsHtml = (0, templates_1.renderOptions)(options.map(function (opt) { return (__assign(__assign({}, opt), { inputValue: inputValue })); }), 'option', this._templateSet);
435
+ }
436
+ break;
437
+ case 'radio':
438
+ tplKey = 'inputRadio';
439
+ if (options.length > 0) {
440
+ optionsHtml = (0, templates_1.renderOptions)(options.map(function (opt) { return (__assign(__assign({}, opt), { inputValue: inputValue })); }), 'radioOption', this._templateSet);
441
+ }
442
+ break;
443
+ case 'checkbox':
444
+ tplKey = 'inputCheckbox';
445
+ if (options.length > 0) {
446
+ optionsHtml = (0, templates_1.renderOptions)(options, 'checkboxOption', this._templateSet);
447
+ }
448
+ break;
449
+ default:
450
+ tplKey = 'inputText';
451
+ break;
452
+ }
453
+ // Use type assertion to satisfy TS for dynamic template keys
454
+ var tpl = this._templateSet[tplKey];
455
+ var data = __assign(__assign({}, this._config), { inputType: inputType, inputPlaceholder: inputPlaceholder, inputValue: inputValue, inputLabel: inputLabel, attrs: attrs, optionsHtml: optionsHtml });
456
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
457
+ return tpl(data);
458
+ }
459
+ else if (typeof tpl === 'string') {
460
+ return (0, templates_1.renderTemplateString)(tpl, data);
461
+ }
462
+ return '';
463
+ };
464
+ /** Render custom content fragment */
465
+ KTAlert.prototype._renderCustomContent = function () {
466
+ if (!this._templateSet.customContent)
467
+ return '';
468
+ var customVal = this._config.customContent || '';
469
+ var tpl = this._templateSet.customContent;
470
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
471
+ return tpl(__assign(__assign({}, this._config), { customContent: customVal }));
472
+ }
473
+ else if (typeof tpl === 'string') {
474
+ return (0, templates_1.renderTemplateString)(tpl, __assign(__assign({}, this._config), { customContent: customVal }));
475
+ }
476
+ return '';
477
+ };
478
+ /** Render confirm button fragment */
479
+ KTAlert.prototype._renderConfirmButton = function () {
480
+ if (!this._config.showConfirmButton)
481
+ return '';
482
+ var confirmText = this._config.confirmText || 'OK';
483
+ var tpl = this._templateSet.confirmButton;
484
+ // Use custom class template if present
485
+ if (this._config.confirmButtonClass && this._templateSet.confirmButtonCustomClass) {
486
+ tpl = this._templateSet.confirmButtonCustomClass;
487
+ }
488
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
489
+ return tpl(__assign(__assign({}, this._config), { confirmText: confirmText, confirmButtonClass: this._config.confirmButtonClass }));
490
+ }
491
+ else if (typeof tpl === 'string') {
492
+ return (0, templates_1.renderTemplateString)(tpl, __assign(__assign({}, this._config), { confirmText: confirmText, confirmButtonClass: this._config.confirmButtonClass }));
493
+ }
494
+ return '';
495
+ };
496
+ /** Render cancel button fragment */
497
+ KTAlert.prototype._renderCancelButton = function () {
498
+ if (!this._config.showCancelButton)
499
+ return '';
500
+ var cancelText = this._config.cancelText || 'Cancel';
501
+ var tpl = this._templateSet.cancelButton;
502
+ // Use custom class template if present
503
+ if (this._config.cancelButtonClass && this._templateSet.cancelButtonCustomClass) {
504
+ tpl = this._templateSet.cancelButtonCustomClass;
505
+ }
506
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
507
+ return tpl(__assign(__assign({}, this._config), { cancelText: cancelText, cancelButtonClass: this._config.cancelButtonClass }));
508
+ }
509
+ else if (typeof tpl === 'string') {
510
+ return (0, templates_1.renderTemplateString)(tpl, __assign(__assign({}, this._config), { cancelText: cancelText, cancelButtonClass: this._config.cancelButtonClass }));
511
+ }
512
+ return '';
513
+ };
514
+ /** Render actions fragment (wraps confirm/cancel buttons) */
515
+ KTAlert.prototype._renderActions = function (confirmButton, cancelButton) {
516
+ if (!this._templateSet.actions)
517
+ return '';
518
+ var tpl = this._templateSet.actions;
519
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
520
+ return tpl(__assign(__assign({}, this._config), { confirmButton: confirmButton, cancelButton: cancelButton }));
521
+ }
522
+ else if (typeof tpl === 'string') {
523
+ return (0, templates_1.renderTemplateString)(tpl, __assign(__assign({}, this._config), { confirmButton: confirmButton, cancelButton: cancelButton }));
524
+ }
525
+ return '';
526
+ };
527
+ /** Render close button fragment */
528
+ KTAlert.prototype._renderCloseButton = function () {
529
+ if (!this._config.showCloseButton || !this._templateSet.closeButton)
530
+ return '';
531
+ var tpl = this._templateSet.closeButton;
532
+ if ((0, templates_1.isTemplateFunction)(tpl)) {
533
+ return tpl(__assign({}, this._config));
534
+ }
535
+ else if (typeof tpl === 'string') {
536
+ return (0, templates_1.renderTemplateString)(tpl, __assign({}, this._config));
537
+ }
538
+ else {
539
+ return '';
540
+ }
541
+ };
542
+ /**
543
+ * Attach event listeners for dismiss, confirm, cancel, and input actions
544
+ * @private
545
+ */
546
+ KTAlert.prototype._bindEvents = function () {
547
+ var _this = this;
548
+ if (!this._container)
549
+ return;
550
+ // Dismiss (close) button
551
+ var closeBtn = this._container.querySelector('[data-kt-alert-close]');
552
+ if (closeBtn) {
553
+ closeBtn.addEventListener('click', function () {
554
+ _this._clearTimer();
555
+ _this._state.isDismissed = true;
556
+ _this._fireEvent('dismiss', {});
557
+ _this._element.innerHTML = '';
558
+ });
559
+ }
560
+ // Confirm button
561
+ var confirmBtn = this._container.querySelector('[data-kt-alert-confirm]');
562
+ if (confirmBtn) {
563
+ confirmBtn.addEventListener('click', function () { return __awaiter(_this, void 0, void 0, function () {
564
+ var inputValue, inputType, checkboxes, radio, inputEl, validationResult, error_1, error_2;
565
+ return __generator(this, function (_a) {
566
+ switch (_a.label) {
567
+ case 0:
568
+ this._clearTimer();
569
+ inputValue = undefined;
570
+ inputType = this._config.inputType || 'text';
571
+ if (inputType === 'checkbox') {
572
+ checkboxes = this._container.querySelectorAll('input[type="checkbox"][data-kt-alert-input]');
573
+ // Return as comma-separated string for type safety
574
+ inputValue = Array.from(checkboxes).filter(function (el) { return el.checked; }).map(function (el) { return el.value; }).join(',');
575
+ }
576
+ else if (inputType === 'radio') {
577
+ radio = this._container.querySelector('input[type="radio"][data-kt-alert-input]:checked');
578
+ inputValue = radio ? radio.value : undefined;
579
+ }
580
+ else {
581
+ inputEl = this._container.querySelector('[data-kt-alert-input]');
582
+ inputValue = inputEl ? inputEl.value : undefined;
583
+ }
584
+ if (!this._config.inputValidator) return [3 /*break*/, 4];
585
+ _a.label = 1;
586
+ case 1:
587
+ _a.trys.push([1, 3, , 4]);
588
+ return [4 /*yield*/, this._config.inputValidator(inputValue || '')];
589
+ case 2:
590
+ validationResult = _a.sent();
591
+ if (validationResult) {
592
+ // Show validation error
593
+ this._showValidationError(validationResult);
594
+ return [2 /*return*/]; // Don't proceed with confirmation
595
+ }
596
+ return [3 /*break*/, 4];
597
+ case 3:
598
+ error_1 = _a.sent();
599
+ // Show validation error for exceptions
600
+ this._showValidationError('Validation failed. Please try again.');
601
+ return [2 /*return*/];
602
+ case 4:
603
+ // Clear any existing validation errors
604
+ this._clearValidationError();
605
+ if (!this._config.preConfirm) return [3 /*break*/, 8];
606
+ _a.label = 5;
607
+ case 5:
608
+ _a.trys.push([5, 7, , 8]);
609
+ return [4 /*yield*/, this._config.preConfirm(inputValue || '')];
610
+ case 6:
611
+ inputValue = _a.sent();
612
+ return [3 /*break*/, 8];
613
+ case 7:
614
+ error_2 = _a.sent();
615
+ // Show error for pre-confirmation failures
616
+ this._showValidationError('Processing failed. Please try again.');
617
+ return [2 /*return*/];
618
+ case 8:
619
+ this._fireEvent('confirm', { inputValue: inputValue });
620
+ this._state.isDismissed = true;
621
+ this._element.innerHTML = '';
622
+ return [2 /*return*/];
623
+ }
624
+ });
625
+ }); });
626
+ }
627
+ // Cancel button
628
+ var cancelBtn = this._container.querySelector('[data-kt-alert-cancel]');
629
+ if (cancelBtn) {
630
+ cancelBtn.addEventListener('click', function () {
631
+ _this._clearTimer();
632
+ _this._fireEvent('cancel', {});
633
+ _this._state.isDismissed = true;
634
+ _this._element.innerHTML = '';
635
+ });
636
+ }
637
+ // Outside click dismissal (for modal alerts)
638
+ if (this._config.modal && this._config.allowOutsideClick) {
639
+ var overlay_1 = this._element.closest('[data-kt-alert-overlay]');
640
+ if (overlay_1) {
641
+ overlay_1.addEventListener('click', function (e) {
642
+ if (e.target === overlay_1) {
643
+ _this._clearTimer();
644
+ _this._state.isDismissed = true;
645
+ _this._fireEvent('dismiss', {});
646
+ _this._element.innerHTML = '';
647
+ }
648
+ });
649
+ }
650
+ }
651
+ // Input field (update state on input/change)
652
+ var inputType = this._config.inputType || 'text';
653
+ if (inputType === 'checkbox' || inputType === 'radio' || inputType === 'select') {
654
+ var inputs = this._container.querySelectorAll('[data-kt-alert-input]');
655
+ inputs.forEach(function (input) {
656
+ input.addEventListener('change', function (e) {
657
+ if (inputType === 'checkbox') {
658
+ var checkboxes = _this._container.querySelectorAll('input[type="checkbox"][data-kt-alert-input]');
659
+ // Store as comma-separated string for type safety
660
+ _this._state.inputValue = Array.from(checkboxes).filter(function (el) { return el.checked; }).map(function (el) { return el.value; }).join(',');
661
+ }
662
+ else if (inputType === 'radio') {
663
+ var radio = _this._container.querySelector('input[type="radio"][data-kt-alert-input]:checked');
664
+ _this._state.inputValue = radio ? radio.value : undefined;
665
+ }
666
+ else if (inputType === 'select') {
667
+ var select = _this._container.querySelector('select[data-kt-alert-input]');
668
+ _this._state.inputValue = select ? select.value : undefined;
669
+ }
670
+ _this._fireEvent('input', { value: _this._state.inputValue });
671
+ });
672
+ });
673
+ }
674
+ else {
675
+ var inputEl = this._container.querySelector('[data-kt-alert-input]');
676
+ if (inputEl) {
677
+ inputEl.addEventListener('input', function (e) {
678
+ _this._state.inputValue = e.target.value;
679
+ _this._fireEvent('input', { value: _this._state.inputValue });
680
+ });
681
+ }
682
+ }
683
+ };
684
+ /**
685
+ * Clear the current timer if it exists.
686
+ * @private
687
+ */
688
+ KTAlert.prototype._clearTimer = function () {
689
+ if (this._timerId) {
690
+ clearTimeout(this._timerId);
691
+ this._timerId = null;
692
+ }
693
+ };
694
+ /**
695
+ * Show validation error message below input field.
696
+ * @private
697
+ */
698
+ KTAlert.prototype._showValidationError = function (message) {
699
+ var _a;
700
+ if (!this._container)
701
+ return;
702
+ // Clear any existing error
703
+ this._clearValidationError();
704
+ // Create error element
705
+ var errorElement = document.createElement('div');
706
+ errorElement.setAttribute('data-kt-alert-input-error', '');
707
+ errorElement.className = 'kt-alert-input-error';
708
+ errorElement.setAttribute('role', 'alert');
709
+ errorElement.setAttribute('aria-live', 'polite');
710
+ errorElement.textContent = message;
711
+ // Find input label and insert error after it
712
+ var inputLabel = this._container.querySelector('[data-kt-alert-input-label]');
713
+ if (inputLabel) {
714
+ (_a = inputLabel.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(errorElement, inputLabel.nextSibling);
715
+ }
716
+ // Mark input as invalid
717
+ var inputElement = this._container.querySelector('[data-kt-alert-input]');
718
+ if (inputElement) {
719
+ inputElement.setAttribute('aria-invalid', 'true');
720
+ }
721
+ };
722
+ /**
723
+ * Clear validation error message.
724
+ * @private
725
+ */
726
+ KTAlert.prototype._clearValidationError = function () {
727
+ if (!this._container)
728
+ return;
729
+ // Remove error element
730
+ var errorElement = this._container.querySelector('[data-kt-alert-input-error]');
731
+ if (errorElement) {
732
+ errorElement.remove();
733
+ }
734
+ // Remove invalid state from input
735
+ var inputElement = this._container.querySelector('[data-kt-alert-input]');
736
+ if (inputElement) {
737
+ inputElement.removeAttribute('aria-invalid');
738
+ }
739
+ };
740
+ /**
741
+ * Show validation error message below input field (static method helper).
742
+ * @private
743
+ */
744
+ KTAlert.showValidationError = function (alert, message) {
745
+ var _a;
746
+ // Clear any existing error
747
+ this.clearValidationError(alert);
748
+ // Create error element
749
+ var errorElement = document.createElement('div');
750
+ errorElement.setAttribute('data-kt-alert-input-error', '');
751
+ errorElement.className = 'kt-alert-input-error';
752
+ errorElement.setAttribute('role', 'alert');
753
+ errorElement.setAttribute('aria-live', 'polite');
754
+ errorElement.textContent = message;
755
+ // Find input label and insert error after it
756
+ var inputLabel = alert.querySelector('[data-kt-alert-input-label]');
757
+ if (inputLabel) {
758
+ (_a = inputLabel.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(errorElement, inputLabel.nextSibling);
759
+ }
760
+ // Mark input as invalid
761
+ var inputElement = alert.querySelector('[data-kt-alert-input]');
762
+ if (inputElement) {
763
+ inputElement.setAttribute('aria-invalid', 'true');
764
+ }
765
+ };
766
+ /**
767
+ * Clear validation error message (static method helper).
768
+ * @private
769
+ */
770
+ KTAlert.clearValidationError = function (alert) {
771
+ // Remove error element
772
+ var errorElement = alert.querySelector('[data-kt-alert-input-error]');
773
+ if (errorElement) {
774
+ errorElement.remove();
775
+ }
776
+ // Remove invalid state from input
777
+ var inputElement = alert.querySelector('[data-kt-alert-input]');
778
+ if (inputElement) {
779
+ inputElement.removeAttribute('aria-invalid');
780
+ }
781
+ };
782
+ /**
783
+ * KTAlert.fire(options)
784
+ * Accepts a config object and returns a Promise that resolves with the user's action and input value.
785
+ */
786
+ KTAlert.fire = function (options) {
787
+ var _this = this;
788
+ var _a;
789
+ // Remove any existing overlay
790
+ var existing = document.querySelector('[data-kt-alert-overlay]');
791
+ if (existing)
792
+ (_a = existing.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(existing);
793
+ // Prepare templates
794
+ var templates = (0, templates_1.getTemplateStrings)(options);
795
+ // Helper to resolve template (string or function)
796
+ function resolveTemplate(tpl, data) {
797
+ if (typeof tpl === 'function')
798
+ return tpl(data);
799
+ return tpl ? (0, templates_1.renderTemplateString)(tpl, data) : '';
800
+ }
801
+ // Set default icon based on type if no explicit icon is provided
802
+ var iconToUse = options.icon === false ? '' : (options.icon || (function () {
803
+ switch (options.type) {
804
+ case 'success': return '✓';
805
+ case 'error': return '✕';
806
+ case 'warning': return '⚠';
807
+ case 'info': return 'ℹ';
808
+ case 'question': return '?';
809
+ default: return '';
810
+ }
811
+ })());
812
+ // Render modal content (all fragments)
813
+ var icon = iconToUse ? resolveTemplate(templates.icon, __assign(__assign({}, options), { icon: iconToUse })) : '';
814
+ var title = resolveTemplate(templates.title, options);
815
+ var message = resolveTemplate(templates.message, __assign(__assign({}, options), { message: options.text || options.message || '' }));
816
+ // Render input based on type
817
+ var input = '';
818
+ if (options.input) {
819
+ var inputType = options.inputType || 'text';
820
+ var inputPlaceholder = options.inputPlaceholder || '';
821
+ var inputValue_1 = options.inputValue || '';
822
+ var inputLabel = options.inputLabel || '';
823
+ var attrs = options.inputAttributes ? Object.entries(options.inputAttributes).map(function (_a) {
824
+ var k = _a[0], v = _a[1];
825
+ return "".concat(k, "=\"").concat(v, "\"");
826
+ }).join(' ') : '';
827
+ var inputOptions = options.inputOptions || [];
828
+ var tplKey = 'inputText';
829
+ var optionsHtml = '';
830
+ // Set template key and render options if needed
831
+ switch (inputType) {
832
+ case 'textarea':
833
+ tplKey = 'inputTextarea';
834
+ break;
835
+ case 'select':
836
+ tplKey = 'inputSelect';
837
+ if (inputOptions.length > 0) {
838
+ optionsHtml = (0, templates_1.renderOptions)(inputOptions.map(function (opt) { return (__assign(__assign({}, opt), { inputValue: inputValue_1 })); }), 'option', templates);
839
+ }
840
+ break;
841
+ case 'radio':
842
+ tplKey = 'inputRadio';
843
+ if (inputOptions.length > 0) {
844
+ optionsHtml = (0, templates_1.renderOptions)(inputOptions.map(function (opt) { return (__assign(__assign({}, opt), { inputValue: inputValue_1 })); }), 'radioOption', templates);
845
+ }
846
+ break;
847
+ case 'checkbox':
848
+ tplKey = 'inputCheckbox';
849
+ if (inputOptions.length > 0) {
850
+ optionsHtml = (0, templates_1.renderOptions)(inputOptions, 'checkboxOption', templates);
851
+ }
852
+ break;
853
+ default:
854
+ tplKey = 'inputText';
855
+ break;
856
+ }
857
+ var inputTemplate = templates[tplKey];
858
+ var inputData = __assign(__assign({}, options), { inputType: inputType, inputPlaceholder: inputPlaceholder, inputValue: inputValue_1, inputLabel: inputLabel, attrs: attrs, optionsHtml: optionsHtml });
859
+ if (typeof inputTemplate === 'string') {
860
+ input = (0, templates_1.renderTemplateString)(inputTemplate, inputData);
861
+ }
862
+ else if (typeof inputTemplate === 'function') {
863
+ input = inputTemplate(inputData);
864
+ }
865
+ }
866
+ var customContent = options.customContent ? resolveTemplate(templates.customContent, options) : '';
867
+ var confirmButton = options.showConfirmButton !== false ? resolveTemplate(templates.confirmButton, __assign(__assign({}, options), { confirmText: options.confirmText || 'OK' })) : '';
868
+ var cancelButton = options.showCancelButton ? resolveTemplate(templates.cancelButton, __assign(__assign({}, options), { cancelText: options.cancelText || 'Cancel' })) : '';
869
+ var actions = resolveTemplate(templates.actions, __assign(__assign({}, options), { confirmButton: confirmButton, cancelButton: cancelButton }));
870
+ var closeButton = options.showCloseButton !== false ? resolveTemplate(templates.closeButton, options) : '';
871
+ // Loader support
872
+ var loaderHtml = options.showLoaderOnConfirm && options.loaderHtml ? resolveTemplate(templates.loaderHtml, options) : '';
873
+ // Compose content
874
+ var content = [icon, title, message, input, customContent, actions, closeButton, loaderHtml].join('');
875
+ // Render modal container
876
+ var modalHtml = resolveTemplate(templates.modal, __assign(__assign({}, options), { type: options.type || 'info', variant: options.variant || '', ariaModal: options.modal !== false ? 'true' : 'false', role: options.modal !== false ? 'alertdialog' : 'alert', content: content, customClass: options.customClass || '', position: options.position || 'center' }));
877
+ // Render overlay (if modal)
878
+ var overlayHtml = options.modal !== false
879
+ ? resolveTemplate(templates.overlay, __assign(__assign({}, options), { modal: modalHtml }))
880
+ : modalHtml;
881
+ // Create DOM node from template
882
+ var temp = document.createElement('div');
883
+ temp.innerHTML = overlayHtml;
884
+ var overlay = options.modal !== false
885
+ ? temp.querySelector('[data-kt-alert-overlay]')
886
+ : temp.firstElementChild;
887
+ document.body.appendChild(overlay);
888
+ // Set custom ID if provided
889
+ var alert = overlay.querySelector('[data-kt-alert]') || overlay;
890
+ if (options.id) {
891
+ alert.id = options.id;
892
+ }
893
+ // Timer support (auto-dismiss)
894
+ var timerId = null;
895
+ // Promise for result
896
+ return new Promise(function (resolve) {
897
+ // Helper to clean up overlay
898
+ var cleanup = function () {
899
+ if (timerId)
900
+ clearTimeout(timerId);
901
+ if (overlay.parentNode)
902
+ overlay.parentNode.removeChild(overlay);
903
+ };
904
+ // Timer support (auto-dismiss) - moved inside Promise to access cleanup and resolve
905
+ if (options.timer && typeof options.timer === 'number' && options.timer > 0) {
906
+ timerId = setTimeout(function () {
907
+ cleanup();
908
+ resolve({ isConfirmed: false, isDismissed: true, isCanceled: false });
909
+ }, options.timer);
910
+ }
911
+ // Bind events manually
912
+ var alert = overlay.querySelector('[data-kt-alert]') || overlay;
913
+ // Dismiss (close) button
914
+ var closeBtn = alert.querySelector('[data-kt-alert-close]');
915
+ if (closeBtn) {
916
+ closeBtn.addEventListener('click', function () {
917
+ cleanup();
918
+ resolve({ isConfirmed: false, isDismissed: true, isCanceled: false });
919
+ });
920
+ }
921
+ // Confirm button
922
+ var confirmBtn = alert.querySelector('[data-kt-alert-confirm]');
923
+ if (confirmBtn) {
924
+ confirmBtn.addEventListener('click', function () { return __awaiter(_this, void 0, void 0, function () {
925
+ var inputValue, inputType, checkboxes, radio, inputEl, validationResult, error_3, error_4;
926
+ return __generator(this, function (_a) {
927
+ switch (_a.label) {
928
+ case 0:
929
+ inputValue = undefined;
930
+ inputType = options.inputType || 'text';
931
+ if (inputType === 'checkbox') {
932
+ checkboxes = alert.querySelectorAll('input[type="checkbox"][data-kt-alert-input]');
933
+ inputValue = Array.from(checkboxes).filter(function (el) { return el.checked; }).map(function (el) { return el.value; }).join(',');
934
+ }
935
+ else if (inputType === 'radio') {
936
+ radio = alert.querySelector('input[type="radio"][data-kt-alert-input]:checked');
937
+ inputValue = radio ? radio.value : undefined;
938
+ }
939
+ else {
940
+ inputEl = alert.querySelector('[data-kt-alert-input]');
941
+ inputValue = inputEl ? inputEl.value : undefined;
942
+ }
943
+ if (!options.inputValidator) return [3 /*break*/, 4];
944
+ _a.label = 1;
945
+ case 1:
946
+ _a.trys.push([1, 3, , 4]);
947
+ return [4 /*yield*/, options.inputValidator(inputValue || '')];
948
+ case 2:
949
+ validationResult = _a.sent();
950
+ if (validationResult) {
951
+ // Show validation error
952
+ KTAlert.showValidationError(alert, validationResult);
953
+ return [2 /*return*/]; // Don't proceed with confirmation
954
+ }
955
+ return [3 /*break*/, 4];
956
+ case 3:
957
+ error_3 = _a.sent();
958
+ // Show validation error for exceptions
959
+ KTAlert.showValidationError(alert, 'Validation failed. Please try again.');
960
+ return [2 /*return*/];
961
+ case 4:
962
+ // Clear any existing validation errors
963
+ KTAlert.clearValidationError(alert);
964
+ if (!options.preConfirm) return [3 /*break*/, 8];
965
+ _a.label = 5;
966
+ case 5:
967
+ _a.trys.push([5, 7, , 8]);
968
+ return [4 /*yield*/, options.preConfirm(inputValue || '')];
969
+ case 6:
970
+ inputValue = _a.sent();
971
+ return [3 /*break*/, 8];
972
+ case 7:
973
+ error_4 = _a.sent();
974
+ // Show error for pre-confirmation failures
975
+ KTAlert.showValidationError(alert, 'Processing failed. Please try again.');
976
+ return [2 /*return*/];
977
+ case 8:
978
+ cleanup();
979
+ resolve({ isConfirmed: true, isDismissed: false, isCanceled: false, value: inputValue });
980
+ return [2 /*return*/];
981
+ }
982
+ });
983
+ }); });
984
+ }
985
+ // Cancel button
986
+ var cancelBtn = alert.querySelector('[data-kt-alert-cancel]');
987
+ if (cancelBtn) {
988
+ cancelBtn.addEventListener('click', function () {
989
+ cleanup();
990
+ resolve({ isConfirmed: false, isDismissed: false, isCanceled: true });
991
+ });
992
+ }
993
+ // Outside click dismissal (for modal alerts)
994
+ if (options.modal && options.allowOutsideClick) {
995
+ overlay.addEventListener('click', function (e) {
996
+ if (e.target === overlay) {
997
+ cleanup();
998
+ resolve({ isConfirmed: false, isDismissed: true, isCanceled: false });
999
+ }
1000
+ });
1001
+ }
1002
+ // Keyboard events
1003
+ alert.addEventListener('keydown', function (e) {
1004
+ if (e.key === 'Escape' && (options.allowEscapeKey !== false || options.dismissible || options.modal)) {
1005
+ cleanup();
1006
+ resolve({ isConfirmed: false, isDismissed: true, isCanceled: false });
1007
+ }
1008
+ if (e.key === 'Enter' && confirmBtn) {
1009
+ confirmBtn.click();
1010
+ }
1011
+ });
1012
+ // Auto-focus input if configured
1013
+ if (options.inputAutoFocus && options.input) {
1014
+ var inputElement_1 = alert.querySelector('[data-kt-alert-input]');
1015
+ if (inputElement_1) {
1016
+ // Use setTimeout to ensure DOM is ready
1017
+ setTimeout(function () { return inputElement_1.focus(); }, 0);
1018
+ }
1019
+ }
1020
+ });
1021
+ };
1022
+ return KTAlert;
1023
+ }(component_1.default));
1024
+ exports.KTAlert = KTAlert;
1025
+ //# sourceMappingURL=alert.js.map