@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,1025 +0,0 @@
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