@keenthemes/ktui 1.1.0 → 1.1.1

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