@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,4 +0,0 @@
1
- // index.ts - Barrel export for KTAlert component and types
2
-
3
- export * from './alert';
4
- export * from './types';
@@ -1,110 +0,0 @@
1
- /*
2
- * templates.ts - Default templates and merging logic for KTAlert (modular alert/dialog component)
3
- * Defines all default template strings and provides merged template set.
4
- *
5
- * Accessibility: All templates include ARIA roles and attributes for screen reader and keyboard support.
6
- */
7
-
8
- import { KTAlertConfig, KTAlertTemplateStrings } from './types';
9
-
10
- // Core template strings for all UI fragments
11
- export const coreTemplateStrings: KTAlertTemplateStrings = {
12
- // Overlay: wraps the modal for modal alerts
13
- overlay: `<div data-kt-alert-overlay aria-hidden="false" class="kt-alert-overlay {{class}}">{{modal}}</div>`,
14
- // Modal container: role=alertdialog for modal, role=alert for non-modal
15
- modal: `<div data-kt-alert data-kt-alert-type="{{type}}" data-kt-alert-variant="{{variant}}" aria-modal="{{ariaModal}}" role="{{role}}" aria-label="Alert Dialog" class="kt-alert-modal {{class}}" data-kt-alert-position="{{position}}">{{content}}</div>`,
16
- // Fallback container (non-modal, or if no template provided)
17
- container: `<div class="kt-alert-container {{class}}">{{content}}</div>`,
18
- icon: `<span data-kt-alert-icon aria-hidden="true" class="kt-alert-icon {{class}}">{{icon}}</span>`,
19
- title: `<h2 data-kt-alert-title id="kt-alert-title" class="kt-alert-title {{class}}">{{title}}</h2>`,
20
- message: `<div data-kt-alert-message id="kt-alert-message" class="kt-alert-message {{class}}">{{message}}</div>`,
21
- actions: `<div data-kt-alert-actions class="kt-alert-actions {{class}}">{{confirmButton}} {{cancelButton}}</div>`,
22
- // Confirm/cancel buttons (default, can be overridden with custom class)
23
- confirmButton: `<button type="button" data-kt-alert-confirm aria-label="Confirm" tabindex="0" class="kt-alert-confirm-button {{class}}">{{confirmText}}</button>`,
24
- cancelButton: `<button type="button" data-kt-alert-cancel aria-label="Cancel" tabindex="0" class="kt-alert-cancel-button {{class}}">{{cancelText}}</button>`,
25
- // Confirm/cancel buttons with custom class (for per-type theming)
26
- confirmButtonCustomClass: `<button type="button" data-kt-alert-confirm aria-label="Confirm" tabindex="0" class="{{confirmButtonClass}}">{{confirmText}}</button>`,
27
- cancelButtonCustomClass: `<button type="button" data-kt-alert-cancel aria-label="Cancel" tabindex="0" class="{{cancelButtonClass}}">{{cancelText}}</button>`,
28
- // Input templates for each type
29
- inputText: `<label data-kt-alert-input-label class="kt-alert-input-label {{inputLabelClass}}">{{inputLabel}}<input data-kt-alert-input type="{{inputType}}" placeholder="{{inputPlaceholder}}" value="{{inputValue}}" {{attrs}} aria-label="Prompt input" tabindex="0" class="kt-alert-input {{inputClass}}" /></label>`,
30
- inputTextarea: `<label data-kt-alert-input-label class="kt-alert-input-label {{inputLabelClass}}">{{inputLabel}}<textarea data-kt-alert-input placeholder="{{inputPlaceholder}}" {{attrs}} aria-label="Prompt input" tabindex="0" class="kt-alert-input {{inputClass}}">{{inputValue}}</textarea></label>`,
31
- inputSelect: `<label data-kt-alert-input-label class="kt-alert-input-label {{inputLabelClass}}">{{inputLabel}}<select data-kt-alert-input {{attrs}} aria-label="Prompt input" tabindex="0" class="kt-alert-input {{inputClass}}">{{optionsHtml}}</select></label>`,
32
- inputRadio: `<fieldset data-kt-alert-input-label class="kt-alert-input-label {{inputLabelClass}}"><legend>{{inputLabel}}</legend>{{optionsHtml}}</fieldset>`,
33
- inputCheckbox: `<fieldset data-kt-alert-input-label class="kt-alert-input-label {{inputLabelClass}}"><legend>{{inputLabel}}</legend>{{optionsHtml}}</fieldset>`,
34
- inputError: `<div data-kt-alert-input-error class="kt-alert-input-error {{class}}" role="alert" aria-live="polite">{{errorMessage}}</div>`,
35
- closeButton: `<button type="button" data-kt-alert-close aria-label="Close alert" tabindex="0" class="kt-alert-close-button {{class}}">&times;</button>`,
36
- customContent: `<div data-kt-alert-custom-content class="kt-alert-custom-content {{class}}">{{customContent}}</div>`,
37
- loaderHtml: `<span data-kt-alert-loader class="kt-alert-loader {{class}}">{{loaderHtml}}</span>`,
38
- // Input option templates
39
- option: `<option value="{{value}}"{{selected}} {{disabled}}>{{label}}</option>`,
40
- radioOption: `<label><input type="radio" name="kt-alert-radio" data-kt-alert-input value="{{value}}"{{checked}} {{disabled}} {{attrs}} aria-label="{{label}}" tabindex="0" />{{label}}</label>`,
41
- checkboxOption: `<label><input type="checkbox" name="kt-alert-checkbox" data-kt-alert-input value="{{value}}"{{checked}} {{disabled}} {{attrs}} aria-label="{{label}}" tabindex="0" />{{label}}</label>`,
42
- };
43
-
44
- /**
45
- * Get the complete template set, merging defaults, user overrides, and config templates.
46
- * @param config Optional config object with a "templates" property.
47
- */
48
- export function getTemplateStrings(config?: KTAlertConfig): KTAlertTemplateStrings {
49
- const templates = config?.templates;
50
- if (templates) {
51
- return { ...coreTemplateStrings, ...userTemplateStrings, ...templates };
52
- }
53
- return { ...coreTemplateStrings, ...userTemplateStrings };
54
- }
55
-
56
- /**
57
- * Renders a template string with data using {{key}} placeholders.
58
- */
59
- export function renderTemplateString(template: string, data: Record<string, any>): string {
60
- return template.replace(/{{(\w+)}}/g, (_, key) =>
61
- data[key] !== undefined ? String(data[key]) : ''
62
- );
63
- }
64
-
65
- /**
66
- * Checks if a template is a function.
67
- */
68
- export function isTemplateFunction(tpl: unknown): tpl is (data: any) => string {
69
- return typeof tpl === 'function';
70
- }
71
-
72
- /**
73
- * User-supplied template overrides. Use setTemplateStrings() to add or update.
74
- */
75
- let userTemplateStrings: Partial<typeof coreTemplateStrings> = {};
76
-
77
- /**
78
- * Register or update user template overrides.
79
- * @param templates Partial template object to merge with defaults.
80
- */
81
- export function setTemplateStrings(templates: Partial<typeof coreTemplateStrings>): void {
82
- userTemplateStrings = { ...userTemplateStrings, ...templates };
83
- }
84
-
85
- /**
86
- * Renders an array of options using a template.
87
- */
88
- export function renderOptions(options: Array<any>, templateKey: string, templateSet: KTAlertTemplateStrings): string {
89
- const template = templateSet[templateKey as keyof KTAlertTemplateStrings];
90
- if (!template) return '';
91
-
92
- return options.map(option => {
93
- const data = {
94
- value: option.value,
95
- label: option.label,
96
- selected: option.value === option.inputValue ? ' selected' : '',
97
- checked: option.checked || false ? ' checked' : '',
98
- disabled: option.disabled || false ? ' disabled' : '',
99
- attrs: option.attrs || ''
100
- };
101
-
102
- if (isTemplateFunction(template)) {
103
- return template(data);
104
- } else if (typeof template === 'string') {
105
- return renderTemplateString(template, data);
106
- }
107
- return '';
108
- }).join('');
109
- }
110
-
@@ -1,19 +0,0 @@
1
- /**
2
- * TEST SUITE: ARIA Roles & Attributes
3
- * PURPOSE: Test ARIA roles/attributes for modal and non-modal alerts
4
- * SCOPE: KTAlert ARIA roles and attributes
5
- * DEPENDENCIES: vitest, jsdom
6
- * LAST UPDATED: 2024-06-08
7
- */
8
-
9
- import { describe, it, expect } from 'vitest';
10
- import { KTAlert } from '../../alert';
11
-
12
- describe('KTAlert ARIA roles and attributes', () => {
13
- it('should set correct ARIA roles and attributes for modal alert', () => {
14
- // TODO: Implement test
15
- });
16
- it('should set correct ARIA roles and attributes for non-modal alert', () => {
17
- // TODO: Implement test
18
- });
19
- });
@@ -1,19 +0,0 @@
1
- /**
2
- * TEST SUITE: Focus Management
3
- * PURPOSE: Test initial focus and focus trap in modal alerts
4
- * SCOPE: KTAlert focus management
5
- * DEPENDENCIES: vitest, jsdom
6
- * LAST UPDATED: 2024-06-08
7
- */
8
-
9
- import { describe, it, expect } from 'vitest';
10
- import { KTAlert } from '../../alert';
11
-
12
- describe('KTAlert focus management', () => {
13
- it('should focus first interactive element on open', () => {
14
- // TODO: Implement test
15
- });
16
- it('should trap focus within modal when open', () => {
17
- // TODO: Implement test
18
- });
19
- });
@@ -1,22 +0,0 @@
1
- /**
2
- * TEST SUITE: Keyboard Navigation
3
- * PURPOSE: Test Tab/Shift+Tab navigation, Enter/Space activation, Escape to close
4
- * SCOPE: KTAlert keyboard navigation
5
- * DEPENDENCIES: vitest, jsdom
6
- * LAST UPDATED: 2024-06-08
7
- */
8
-
9
- import { describe, it, expect } from 'vitest';
10
- import { KTAlert } from '../../alert';
11
-
12
- describe('KTAlert keyboard navigation', () => {
13
- it('should allow Tab and Shift+Tab navigation between interactive elements', () => {
14
- // TODO: Implement test
15
- });
16
- it('should activate confirm on Enter/Space', () => {
17
- // TODO: Implement test
18
- });
19
- it('should close alert on Escape if allowed', () => {
20
- // TODO: Implement test
21
- });
22
- });
@@ -1,122 +0,0 @@
1
- /**
2
- * TEST SUITE: Confirm/Cancel Actions
3
- * PURPOSE: Test confirm and cancel button flows, event firing, and result values
4
- * SCOPE: KTAlert confirm/cancel actions
5
- * DEPENDENCIES: vitest, jsdom
6
- * LAST UPDATED: 2024-06-08
7
- */
8
-
9
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
10
- import { KTAlert } from '../../alert';
11
-
12
- describe('KTAlert confirm/cancel actions', () => {
13
- beforeEach(() => {
14
- document.body.innerHTML = '';
15
- });
16
- afterEach(() => {
17
- document.body.innerHTML = '';
18
- });
19
-
20
- it('should fire confirm event and resolve with correct value', () => {
21
- // ARRANGE
22
- const element = document.createElement('div');
23
- document.body.appendChild(element);
24
- const alert = new KTAlert(element, { showConfirmButton: true });
25
- const fireEventSpy = vi.spyOn(alert as any, '_fireEvent');
26
- // ACT
27
- const confirmButton = element.querySelector('[data-kt-alert-confirm]') as HTMLElement;
28
- confirmButton?.click();
29
- // ASSERT
30
- expect(fireEventSpy).toHaveBeenCalledWith('confirm', { inputValue: undefined });
31
- expect((alert as any)._state.isDismissed).toBe(true);
32
- expect(element.innerHTML).toBe('');
33
- });
34
-
35
- it('should fire cancel event and resolve with correct value', () => {
36
- // ARRANGE
37
- const element = document.createElement('div');
38
- document.body.appendChild(element);
39
- const alert = new KTAlert(element, { showCancelButton: true });
40
- const fireEventSpy = vi.spyOn(alert as any, '_fireEvent');
41
- // ACT
42
- const cancelButton = element.querySelector('[data-kt-alert-cancel]') as HTMLElement;
43
- cancelButton?.click();
44
- // ASSERT
45
- expect(fireEventSpy).toHaveBeenCalledWith('cancel', {});
46
- expect((alert as any)._state.isDismissed).toBe(true);
47
- expect(element.innerHTML).toBe('');
48
- });
49
-
50
- it('should use custom button text if provided', () => {
51
- // ARRANGE
52
- const element = document.createElement('div');
53
- document.body.appendChild(element);
54
- const alert = new KTAlert(element, {
55
- showConfirmButton: true,
56
- showCancelButton: true,
57
- confirmText: 'Yes, do it!',
58
- cancelText: 'No, cancel'
59
- });
60
- // ACT
61
- const confirmButton = element.querySelector('[data-kt-alert-confirm]') as HTMLElement;
62
- const cancelButton = element.querySelector('[data-kt-alert-cancel]') as HTMLElement;
63
- // ASSERT
64
- expect(confirmButton?.textContent).toBe('Yes, do it!');
65
- expect(cancelButton?.textContent).toBe('No, cancel');
66
- });
67
-
68
- it('should not render buttons if showConfirmButton and showCancelButton are false', () => {
69
- // ARRANGE
70
- const element = document.createElement('div');
71
- document.body.appendChild(element);
72
- const alert = new KTAlert(element, {
73
- showConfirmButton: false,
74
- showCancelButton: false
75
- });
76
- // ACT
77
- const confirmButton = element.querySelector('[data-kt-alert-confirm]');
78
- const cancelButton = element.querySelector('[data-kt-alert-cancel]');
79
- // ASSERT
80
- expect(confirmButton).toBeNull();
81
- expect(cancelButton).toBeNull();
82
- });
83
-
84
- it('should clear timer when confirm button is clicked', () => {
85
- // ARRANGE
86
- const element = document.createElement('div');
87
- document.body.appendChild(element);
88
- const alert = new KTAlert(element, { showConfirmButton: true, timer: 5000 });
89
- const clearTimerSpy = vi.spyOn(alert as any, '_clearTimer');
90
- // ACT
91
- const confirmButton = element.querySelector('[data-kt-alert-confirm]') as HTMLElement;
92
- confirmButton?.click();
93
- // ASSERT
94
- expect(clearTimerSpy).toHaveBeenCalled();
95
- });
96
-
97
- it('should clear timer when cancel button is clicked', () => {
98
- // ARRANGE
99
- const element = document.createElement('div');
100
- document.body.appendChild(element);
101
- const alert = new KTAlert(element, { showCancelButton: true, timer: 5000 });
102
- const clearTimerSpy = vi.spyOn(alert as any, '_clearTimer');
103
- // ACT
104
- const cancelButton = element.querySelector('[data-kt-alert-cancel]') as HTMLElement;
105
- cancelButton?.click();
106
- // ASSERT
107
- expect(clearTimerSpy).toHaveBeenCalled();
108
- });
109
-
110
- it('should handle Enter key to trigger confirm button', () => {
111
- // ARRANGE
112
- const config = { showConfirmButton: true, title: 'Test' };
113
- // ACT
114
- KTAlert.fire(config);
115
- const alert = document.querySelector('[data-kt-alert]');
116
- const enterEvent = new KeyboardEvent('keydown', { key: 'Enter', bubbles: true });
117
- alert?.dispatchEvent(enterEvent);
118
- // ASSERT
119
- // The alert should be dismissed (confirm button clicked)
120
- expect(document.querySelector('[data-kt-alert-overlay]')).toBeNull();
121
- });
122
- });
@@ -1,180 +0,0 @@
1
- /**
2
- * TEST SUITE: Input Field Actions
3
- * PURPOSE: Test alerts with input fields (text, textarea, select, radio, checkbox), value propagation
4
- * SCOPE: KTAlert input field handling
5
- * DEPENDENCIES: vitest, jsdom
6
- * LAST UPDATED: 2024-06-08
7
- */
8
-
9
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
10
- import { KTAlert } from '../../alert';
11
-
12
- describe('KTAlert input field actions', () => {
13
- beforeEach(() => {
14
- document.body.innerHTML = '';
15
- });
16
- afterEach(() => {
17
- document.body.innerHTML = '';
18
- });
19
-
20
- it('should propagate value from text input', () => {
21
- // ARRANGE
22
- const config = {
23
- input: true,
24
- inputType: 'text',
25
- inputPlaceholder: 'Enter text',
26
- showConfirmButton: true,
27
- title: 'Test'
28
- };
29
- // ACT
30
- KTAlert.fire(config);
31
- const input = document.querySelector('input[type="text"]') as HTMLInputElement;
32
- input.value = 'test value';
33
- const confirmButton = document.querySelector('[data-kt-alert-confirm]') as HTMLElement;
34
- confirmButton?.click();
35
- // ASSERT
36
- // The alert should be dismissed with the input value
37
- expect(document.querySelector('[data-kt-alert-overlay]')).toBeNull();
38
- });
39
-
40
- it('should propagate value from textarea input', () => {
41
- // ARRANGE
42
- const config = {
43
- input: true,
44
- inputType: 'textarea',
45
- inputPlaceholder: 'Enter text',
46
- showConfirmButton: true,
47
- title: 'Test'
48
- };
49
- // ACT
50
- KTAlert.fire(config);
51
- const textarea = document.querySelector('textarea') as HTMLTextAreaElement;
52
- textarea.value = 'multiline\ntext';
53
- const confirmButton = document.querySelector('[data-kt-alert-confirm]') as HTMLElement;
54
- confirmButton?.click();
55
- // ASSERT
56
- // The alert should be dismissed with the input value
57
- expect(document.querySelector('[data-kt-alert-overlay]')).toBeNull();
58
- });
59
-
60
- it('should propagate value from select input', () => {
61
- // ARRANGE
62
- const config = {
63
- input: true,
64
- inputType: 'select',
65
- inputOptions: [
66
- { value: 'option1', label: 'Option 1' },
67
- { value: 'option2', label: 'Option 2' }
68
- ],
69
- showConfirmButton: true,
70
- title: 'Test'
71
- };
72
- // ACT
73
- KTAlert.fire(config);
74
- const select = document.querySelector('select') as HTMLSelectElement;
75
- select.value = 'option2';
76
- const confirmButton = document.querySelector('[data-kt-alert-confirm]') as HTMLElement;
77
- confirmButton?.click();
78
- // ASSERT
79
- // The alert should be dismissed with the input value
80
- expect(document.querySelector('[data-kt-alert-overlay]')).toBeNull();
81
- });
82
-
83
- it('should propagate value from radio input', () => {
84
- // ARRANGE
85
- const config = {
86
- input: true,
87
- inputType: 'radio',
88
- inputOptions: [
89
- { value: 'radio1', label: 'Radio 1' },
90
- { value: 'radio2', label: 'Radio 2', checked: true }
91
- ],
92
- showConfirmButton: true,
93
- title: 'Test'
94
- };
95
- // ACT
96
- KTAlert.fire(config);
97
- const confirmButton = document.querySelector('[data-kt-alert-confirm]') as HTMLElement;
98
- confirmButton?.click();
99
- // ASSERT
100
- // The alert should be dismissed with the input value
101
- expect(document.querySelector('[data-kt-alert-overlay]')).toBeNull();
102
- });
103
-
104
- it('should propagate value from checkbox input', () => {
105
- // ARRANGE
106
- const config = {
107
- input: true,
108
- inputType: 'checkbox',
109
- inputOptions: [
110
- { value: 'check1', label: 'Check 1' },
111
- { value: 'check2', label: 'Check 2' }
112
- ],
113
- showConfirmButton: true,
114
- title: 'Test'
115
- };
116
- // ACT
117
- KTAlert.fire(config);
118
- const checkboxes = document.querySelectorAll('input[type="checkbox"]') as NodeListOf<HTMLInputElement>;
119
- checkboxes[0].checked = true;
120
- checkboxes[1].checked = true;
121
- const confirmButton = document.querySelector('[data-kt-alert-confirm]') as HTMLElement;
122
- confirmButton?.click();
123
- // ASSERT
124
- // The alert should be dismissed with the input value
125
- expect(document.querySelector('[data-kt-alert-overlay]')).toBeNull();
126
- });
127
-
128
- it('should handle input change events', () => {
129
- // ARRANGE
130
- const config = {
131
- input: true,
132
- inputType: 'text',
133
- showConfirmButton: true,
134
- title: 'Test'
135
- };
136
- // ACT
137
- KTAlert.fire(config);
138
- const input = document.querySelector('input[type="text"]') as HTMLInputElement;
139
- input.value = 'new value';
140
- input.dispatchEvent(new Event('input', { bubbles: true }));
141
- // ASSERT
142
- // The input value should be updated
143
- expect(input.value).toBe('new value');
144
- });
145
-
146
- it('should not render input if input is false', () => {
147
- // ARRANGE
148
- const config = {
149
- input: false,
150
- showConfirmButton: true,
151
- title: 'Test'
152
- };
153
- // ACT
154
- KTAlert.fire(config);
155
- const input = document.querySelector('input, textarea, select');
156
- // ASSERT
157
- expect(input).toBeNull();
158
- });
159
-
160
- it('should apply input attributes correctly', () => {
161
- // ARRANGE
162
- const config = {
163
- input: true,
164
- inputType: 'text',
165
- inputAttributes: {
166
- maxlength: '10',
167
- required: 'true',
168
- pattern: '[A-Za-z]+'
169
- },
170
- title: 'Test'
171
- };
172
- // ACT
173
- KTAlert.fire(config);
174
- const input = document.querySelector('input[type="text"]') as HTMLInputElement;
175
- // ASSERT
176
- expect(input?.getAttribute('maxlength')).toBe('10');
177
- expect(input?.getAttribute('required')).toBe('true');
178
- expect(input?.getAttribute('pattern')).toBe('[A-Za-z]+');
179
- });
180
- });
@@ -1,126 +0,0 @@
1
- // alert.basic.test.ts - Basic instantiation and type safety tests for KTAlert
2
- import { describe, it, expect } from 'vitest';
3
- import { KTAlert } from '../alert';
4
- import { vi } from 'vitest';
5
-
6
- describe('KTAlert', () => {
7
- it('should instantiate without errors', () => {
8
- // Create a dummy element
9
- const el = document.createElement('div');
10
- // Instantiate KTAlert
11
- const alert = new KTAlert(document.createElement("div"));
12
- // Should be defined
13
- expect(alert).toBeDefined();
14
- // Should have correct name
15
- expect((alert as any)._name).toBe('alert');
16
- });
17
-
18
- it('should auto-dismiss after timer expires', async () => {
19
- vi.useFakeTimers();
20
- const el = document.createElement('div');
21
- document.body.appendChild(el);
22
- const alert = new KTAlert(el, { timer: 1000, dismissible: true });
23
- // Spy on _fireEvent
24
- const fireEventSpy = vi.spyOn(alert as any, '_fireEvent');
25
- // Fast-forward time
26
- vi.advanceTimersByTime(1000);
27
- // Wait for microtasks
28
- await vi.runAllTicks();
29
- expect(fireEventSpy).toHaveBeenCalledWith('dismiss', { reason: 'timer' });
30
- expect(el.innerHTML).toBe('');
31
- vi.useRealTimers();
32
- });
33
-
34
- it('should not auto-dismiss if manually dismissed first', async () => {
35
- vi.useFakeTimers();
36
- const el = document.createElement('div');
37
- document.body.appendChild(el);
38
- const alert = new KTAlert(el, { timer: 1000, dismissible: true });
39
- // Spy on _fireEvent
40
- const fireEventSpy = vi.spyOn(alert as any, '_fireEvent');
41
- // Simulate manual dismiss
42
- (alert as any)._clearTimer();
43
- (alert as any)._state.isDismissed = true;
44
- (alert as any)._element.innerHTML = '';
45
- // Fast-forward time
46
- vi.advanceTimersByTime(1000);
47
- // Wait for microtasks
48
- await vi.runAllTicks();
49
- // Should not call _fireEvent again for timer
50
- expect(fireEventSpy).not.toHaveBeenCalledWith('dismiss', { reason: 'timer' });
51
- vi.useRealTimers();
52
- });
53
- });
54
-
55
- describe('KTAlert input types', () => {
56
- it('should render and capture text input', () => {
57
- const el = document.createElement('div');
58
- document.body.appendChild(el);
59
- const alert = new KTAlert(el, { input: true, inputType: 'text', inputValue: 'foo' });
60
- const input = el.querySelector('input[data-kt-alert-input]') as HTMLInputElement;
61
- expect(input).toBeDefined();
62
- expect(input.value).toBe('foo');
63
- input.value = 'bar';
64
- input.dispatchEvent(new Event('input'));
65
- expect((alert as any)._state.inputValue).toBe('bar');
66
- });
67
-
68
- it('should render and capture textarea input', () => {
69
- const el = document.createElement('div');
70
- document.body.appendChild(el);
71
- const alert = new KTAlert(el, { input: true, inputType: 'textarea', inputValue: 'foo' });
72
- const textarea = el.querySelector('textarea[data-kt-alert-input]') as HTMLTextAreaElement;
73
- expect(textarea).toBeDefined();
74
- expect(textarea.value).toBe('foo');
75
- textarea.value = 'bar';
76
- textarea.dispatchEvent(new Event('input'));
77
- expect((alert as any)._state.inputValue).toBe('bar');
78
- });
79
-
80
- it('should render and capture select input', () => {
81
- const el = document.createElement('div');
82
- document.body.appendChild(el);
83
- const alert = new KTAlert(el, { input: true, inputType: 'select', inputValue: 'b', inputOptions: [
84
- { value: 'a', label: 'A' },
85
- { value: 'b', label: 'B' },
86
- { value: 'c', label: 'C' },
87
- ] });
88
- const select = el.querySelector('select[data-kt-alert-input]') as HTMLSelectElement;
89
- expect(select).toBeDefined();
90
- expect(select.value).toBe('b');
91
- select.value = 'c';
92
- select.dispatchEvent(new Event('change'));
93
- expect((alert as any)._state.inputValue).toBe('c');
94
- });
95
-
96
- it('should render and capture radio input', () => {
97
- const el = document.createElement('div');
98
- document.body.appendChild(el);
99
- const alert = new KTAlert(el, { input: true, inputType: 'radio', inputValue: 'b', inputOptions: [
100
- { value: 'a', label: 'A' },
101
- { value: 'b', label: 'B' },
102
- { value: 'c', label: 'C' },
103
- ] });
104
- const radios = el.querySelectorAll('input[type="radio"][data-kt-alert-input]') as NodeListOf<HTMLInputElement>;
105
- expect(radios.length).toBe(3);
106
- radios[2].checked = true;
107
- radios[2].dispatchEvent(new Event('change'));
108
- expect((alert as any)._state.inputValue).toBe('c');
109
- });
110
-
111
- it('should render and capture checkbox input', () => {
112
- const el = document.createElement('div');
113
- document.body.appendChild(el);
114
- const alert = new KTAlert(el, { input: true, inputType: 'checkbox', inputOptions: [
115
- { value: 'a', label: 'A', checked: true },
116
- { value: 'b', label: 'B' },
117
- { value: 'c', label: 'C', checked: true },
118
- ] });
119
- const checkboxes = el.querySelectorAll('input[type="checkbox"][data-kt-alert-input]') as NodeListOf<HTMLInputElement>;
120
- expect(checkboxes.length).toBe(3);
121
- checkboxes[1].checked = true;
122
- checkboxes[1].dispatchEvent(new Event('change'));
123
- // Should be comma-separated string of checked values
124
- expect((alert as any)._state.inputValue.split(',').sort()).toEqual(['a','b','c'].sort());
125
- });
126
- });