@keenthemes/ktui 1.2.6 → 1.2.7

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 (190) hide show
  1. package/README.md +14 -5
  2. package/dist/ktui.js +3775 -2298
  3. package/dist/ktui.min.js +1 -1
  4. package/dist/ktui.min.js.map +1 -1
  5. package/dist/styles.css +25 -5
  6. package/lib/cjs/components/datatable/datatable-checkbox.d.ts +37 -1
  7. package/lib/cjs/components/datatable/datatable-checkbox.d.ts.map +1 -1
  8. package/lib/cjs/components/datatable/datatable-checkbox.js +143 -156
  9. package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
  10. package/lib/cjs/components/datatable/datatable-column-utils.d.ts +30 -0
  11. package/lib/cjs/components/datatable/datatable-column-utils.d.ts.map +1 -0
  12. package/lib/cjs/components/datatable/datatable-column-utils.js +42 -0
  13. package/lib/cjs/components/datatable/datatable-column-utils.js.map +1 -0
  14. package/lib/cjs/components/datatable/datatable-contracts.d.ts +2 -4
  15. package/lib/cjs/components/datatable/datatable-contracts.d.ts.map +1 -1
  16. package/lib/cjs/components/datatable/datatable-defaults.d.ts +20 -0
  17. package/lib/cjs/components/datatable/datatable-defaults.d.ts.map +1 -0
  18. package/lib/cjs/components/datatable/datatable-defaults.js +193 -0
  19. package/lib/cjs/components/datatable/datatable-defaults.js.map +1 -0
  20. package/lib/cjs/components/datatable/datatable-layout-plugin.d.ts.map +1 -1
  21. package/lib/cjs/components/datatable/datatable-layout-plugin.js +11 -1
  22. package/lib/cjs/components/datatable/datatable-layout-plugin.js.map +1 -1
  23. package/lib/cjs/components/datatable/datatable-local-provider.d.ts.map +1 -1
  24. package/lib/cjs/components/datatable/datatable-local-provider.js +80 -24
  25. package/lib/cjs/components/datatable/datatable-local-provider.js.map +1 -1
  26. package/lib/cjs/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  27. package/lib/cjs/components/datatable/datatable-pagination-renderer.js +3 -2
  28. package/lib/cjs/components/datatable/datatable-pagination-renderer.js.map +1 -1
  29. package/lib/cjs/components/datatable/datatable-registry.d.ts +18 -0
  30. package/lib/cjs/components/datatable/datatable-registry.d.ts.map +1 -0
  31. package/lib/cjs/components/datatable/datatable-registry.js +66 -0
  32. package/lib/cjs/components/datatable/datatable-registry.js.map +1 -0
  33. package/lib/cjs/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  34. package/lib/cjs/components/datatable/datatable-remote-provider.js +1 -2
  35. package/lib/cjs/components/datatable/datatable-remote-provider.js.map +1 -1
  36. package/lib/cjs/components/datatable/datatable-search-handler.d.ts +10 -0
  37. package/lib/cjs/components/datatable/datatable-search-handler.d.ts.map +1 -0
  38. package/lib/cjs/components/datatable/datatable-search-handler.js +65 -0
  39. package/lib/cjs/components/datatable/datatable-search-handler.js.map +1 -0
  40. package/lib/cjs/components/datatable/datatable-sort.d.ts +31 -4
  41. package/lib/cjs/components/datatable/datatable-sort.d.ts.map +1 -1
  42. package/lib/cjs/components/datatable/datatable-sort.js +86 -58
  43. package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
  44. package/lib/cjs/components/datatable/datatable-spinner.d.ts +30 -0
  45. package/lib/cjs/components/datatable/datatable-spinner.d.ts.map +1 -0
  46. package/lib/cjs/components/datatable/datatable-spinner.js +54 -0
  47. package/lib/cjs/components/datatable/datatable-spinner.js.map +1 -0
  48. package/lib/cjs/components/datatable/datatable-state-persistence.d.ts +19 -0
  49. package/lib/cjs/components/datatable/datatable-state-persistence.d.ts.map +1 -0
  50. package/lib/cjs/components/datatable/datatable-state-persistence.js +59 -0
  51. package/lib/cjs/components/datatable/datatable-state-persistence.js.map +1 -0
  52. package/lib/cjs/components/datatable/datatable-table-renderer.d.ts +2 -0
  53. package/lib/cjs/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  54. package/lib/cjs/components/datatable/datatable-table-renderer.js +75 -16
  55. package/lib/cjs/components/datatable/datatable-table-renderer.js.map +1 -1
  56. package/lib/cjs/components/datatable/datatable-utils.d.ts +10 -0
  57. package/lib/cjs/components/datatable/datatable-utils.d.ts.map +1 -0
  58. package/lib/cjs/components/datatable/datatable-utils.js +15 -0
  59. package/lib/cjs/components/datatable/datatable-utils.js.map +1 -0
  60. package/lib/cjs/components/datatable/datatable.d.ts +26 -34
  61. package/lib/cjs/components/datatable/datatable.d.ts.map +1 -1
  62. package/lib/cjs/components/datatable/datatable.js +155 -492
  63. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  64. package/lib/cjs/components/datatable/index.d.ts +1 -1
  65. package/lib/cjs/components/datatable/index.d.ts.map +1 -1
  66. package/lib/cjs/components/datatable/types.d.ts +100 -11
  67. package/lib/cjs/components/datatable/types.d.ts.map +1 -1
  68. package/lib/cjs/index.d.ts +1 -1
  69. package/lib/cjs/index.d.ts.map +1 -1
  70. package/lib/cjs/index.js +6 -0
  71. package/lib/cjs/index.js.map +1 -1
  72. package/lib/esm/components/datatable/datatable-checkbox.d.ts +37 -1
  73. package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -1
  74. package/lib/esm/components/datatable/datatable-checkbox.js +142 -155
  75. package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
  76. package/lib/esm/components/datatable/datatable-column-utils.d.ts +30 -0
  77. package/lib/esm/components/datatable/datatable-column-utils.d.ts.map +1 -0
  78. package/lib/esm/components/datatable/datatable-column-utils.js +38 -0
  79. package/lib/esm/components/datatable/datatable-column-utils.js.map +1 -0
  80. package/lib/esm/components/datatable/datatable-contracts.d.ts +2 -4
  81. package/lib/esm/components/datatable/datatable-contracts.d.ts.map +1 -1
  82. package/lib/esm/components/datatable/datatable-defaults.d.ts +20 -0
  83. package/lib/esm/components/datatable/datatable-defaults.d.ts.map +1 -0
  84. package/lib/esm/components/datatable/datatable-defaults.js +190 -0
  85. package/lib/esm/components/datatable/datatable-defaults.js.map +1 -0
  86. package/lib/esm/components/datatable/datatable-layout-plugin.d.ts.map +1 -1
  87. package/lib/esm/components/datatable/datatable-layout-plugin.js +11 -1
  88. package/lib/esm/components/datatable/datatable-layout-plugin.js.map +1 -1
  89. package/lib/esm/components/datatable/datatable-local-provider.d.ts.map +1 -1
  90. package/lib/esm/components/datatable/datatable-local-provider.js +80 -24
  91. package/lib/esm/components/datatable/datatable-local-provider.js.map +1 -1
  92. package/lib/esm/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  93. package/lib/esm/components/datatable/datatable-pagination-renderer.js +3 -2
  94. package/lib/esm/components/datatable/datatable-pagination-renderer.js.map +1 -1
  95. package/lib/esm/components/datatable/datatable-registry.d.ts +18 -0
  96. package/lib/esm/components/datatable/datatable-registry.d.ts.map +1 -0
  97. package/lib/esm/components/datatable/datatable-registry.js +63 -0
  98. package/lib/esm/components/datatable/datatable-registry.js.map +1 -0
  99. package/lib/esm/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  100. package/lib/esm/components/datatable/datatable-remote-provider.js +1 -2
  101. package/lib/esm/components/datatable/datatable-remote-provider.js.map +1 -1
  102. package/lib/esm/components/datatable/datatable-search-handler.d.ts +10 -0
  103. package/lib/esm/components/datatable/datatable-search-handler.d.ts.map +1 -0
  104. package/lib/esm/components/datatable/datatable-search-handler.js +62 -0
  105. package/lib/esm/components/datatable/datatable-search-handler.js.map +1 -0
  106. package/lib/esm/components/datatable/datatable-sort.d.ts +31 -4
  107. package/lib/esm/components/datatable/datatable-sort.d.ts.map +1 -1
  108. package/lib/esm/components/datatable/datatable-sort.js +85 -57
  109. package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
  110. package/lib/esm/components/datatable/datatable-spinner.d.ts +30 -0
  111. package/lib/esm/components/datatable/datatable-spinner.d.ts.map +1 -0
  112. package/lib/esm/components/datatable/datatable-spinner.js +51 -0
  113. package/lib/esm/components/datatable/datatable-spinner.js.map +1 -0
  114. package/lib/esm/components/datatable/datatable-state-persistence.d.ts +19 -0
  115. package/lib/esm/components/datatable/datatable-state-persistence.d.ts.map +1 -0
  116. package/lib/esm/components/datatable/datatable-state-persistence.js +55 -0
  117. package/lib/esm/components/datatable/datatable-state-persistence.js.map +1 -0
  118. package/lib/esm/components/datatable/datatable-table-renderer.d.ts +2 -0
  119. package/lib/esm/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  120. package/lib/esm/components/datatable/datatable-table-renderer.js +75 -16
  121. package/lib/esm/components/datatable/datatable-table-renderer.js.map +1 -1
  122. package/lib/esm/components/datatable/datatable-utils.d.ts +10 -0
  123. package/lib/esm/components/datatable/datatable-utils.d.ts.map +1 -0
  124. package/lib/esm/components/datatable/datatable-utils.js +12 -0
  125. package/lib/esm/components/datatable/datatable-utils.js.map +1 -0
  126. package/lib/esm/components/datatable/datatable.d.ts +26 -34
  127. package/lib/esm/components/datatable/datatable.d.ts.map +1 -1
  128. package/lib/esm/components/datatable/datatable.js +157 -494
  129. package/lib/esm/components/datatable/datatable.js.map +1 -1
  130. package/lib/esm/components/datatable/index.d.ts +1 -1
  131. package/lib/esm/components/datatable/index.d.ts.map +1 -1
  132. package/lib/esm/components/datatable/types.d.ts +100 -11
  133. package/lib/esm/components/datatable/types.d.ts.map +1 -1
  134. package/lib/esm/index.d.ts +1 -1
  135. package/lib/esm/index.d.ts.map +1 -1
  136. package/lib/esm/index.js +6 -0
  137. package/lib/esm/index.js.map +1 -1
  138. package/package.json +5 -1
  139. package/skills/ktui/SKILL.md +711 -0
  140. package/skills/ktui-datatable/SKILL.md +302 -0
  141. package/skills/ktui-install/SKILL.md +150 -0
  142. package/skills/ktui-select/SKILL.md +271 -0
  143. package/src/components/__tests__/component.test.ts +347 -0
  144. package/src/components/collapse/collapse.css +2 -2
  145. package/src/components/datatable/__tests__/architecture-boundaries.test.ts +56 -8
  146. package/src/components/datatable/__tests__/currency-sort.test.ts +25 -28
  147. package/src/components/datatable/__tests__/datatable-checkbox.test.ts +527 -0
  148. package/src/components/datatable/__tests__/datatable-column-utils.test.ts +117 -0
  149. package/src/components/datatable/__tests__/datatable-defaults.test.ts +57 -0
  150. package/src/components/datatable/__tests__/datatable-finalize-extended.test.ts +361 -0
  151. package/src/components/datatable/__tests__/datatable-fixed-layout.test.ts +427 -0
  152. package/src/components/datatable/__tests__/datatable-improvements.test.ts +484 -0
  153. package/src/components/datatable/__tests__/datatable-pagination-extended.test.ts +508 -0
  154. package/src/components/datatable/__tests__/datatable-public-api.test.ts +269 -0
  155. package/src/components/datatable/__tests__/datatable-registry.test.ts +172 -0
  156. package/src/components/datatable/__tests__/datatable-remote-provider.test.ts +468 -0
  157. package/src/components/datatable/__tests__/datatable-search-handler.test.ts +124 -0
  158. package/src/components/datatable/__tests__/datatable-sort-extended.test.ts +417 -0
  159. package/src/components/datatable/__tests__/datatable-spinner.test.ts +95 -0
  160. package/src/components/datatable/__tests__/datatable-table-renderer-extended.test.ts +425 -0
  161. package/src/components/datatable/__tests__/datatable-types.test.ts +117 -0
  162. package/src/components/datatable/__tests__/datatable-utils.test.ts +52 -0
  163. package/src/components/datatable/__tests__/multi-row-headers.test.ts +7 -7
  164. package/src/components/datatable/__tests__/pagination-reset.test.ts +129 -6
  165. package/src/components/datatable/__tests__/race-conditions.test.ts +11 -11
  166. package/src/components/datatable/__tests__/setup.ts +12 -4
  167. package/src/components/datatable/datatable-checkbox.ts +144 -145
  168. package/src/components/datatable/datatable-column-utils.ts +63 -0
  169. package/src/components/datatable/datatable-contracts.ts +2 -3
  170. package/src/components/datatable/datatable-defaults.ts +204 -0
  171. package/src/components/datatable/datatable-layout-plugin.ts +11 -1
  172. package/src/components/datatable/datatable-local-provider.ts +91 -28
  173. package/src/components/datatable/datatable-pagination-renderer.ts +3 -2
  174. package/src/components/datatable/datatable-registry.ts +89 -0
  175. package/src/components/datatable/datatable-remote-provider.ts +1 -3
  176. package/src/components/datatable/datatable-search-handler.ts +97 -0
  177. package/src/components/datatable/datatable-sort.ts +111 -66
  178. package/src/components/datatable/datatable-spinner.ts +103 -0
  179. package/src/components/datatable/datatable-state-persistence.ts +67 -0
  180. package/src/components/datatable/datatable-table-renderer.ts +81 -18
  181. package/src/components/datatable/datatable-utils.ts +12 -0
  182. package/src/components/datatable/datatable.ts +191 -580
  183. package/src/components/datatable/index.ts +3 -0
  184. package/src/components/datatable/types.ts +124 -23
  185. package/src/helpers/__tests__/dom.test.ts +776 -0
  186. package/src/helpers/__tests__/utils.test.ts +332 -0
  187. package/src/index.ts +10 -0
  188. package/skills/ktui-components/SKILL.md +0 -41
  189. package/skills/ktui-theming/SKILL.md +0 -50
  190. package/src/components/datatable/datatable-event-adapter.ts +0 -21
@@ -0,0 +1,711 @@
1
+ ---
2
+ name: ktui
3
+ description: >
4
+ Comprehensive guide to KtUI (Keenthemes Tailwind UI) — components, theming,
5
+ initialization, data-attribute API, event system, helpers, and common patterns.
6
+ Use this skill when building UI with KtUI, adding/customizing components,
7
+ working with KtUI theming/colors/dark-mode, or when the user mentions
8
+ KtUI, ktui, Keenthemes components, or Tailwind UI components from Keenthemes.
9
+ ---
10
+
11
+ # KtUI — AI Agent Reference
12
+
13
+ [KtUI](https://ktui.io) is a free, open-source Tailwind CSS component library by Keenthemes.
14
+ Package: `@keenthemes/ktui` (npm).
15
+
16
+ > **Always prefer [ktui.io](https://ktui.io) docs and examples over guessing markup or options.**
17
+
18
+ ---
19
+
20
+ ## 1. Installation & Setup
21
+
22
+ > **See the `ktui-install` skill** for full installation, Tailwind config, framework integration, SSR, dark mode setup, and troubleshooting.
23
+
24
+ ```bash
25
+ npm install @keenthemes/ktui
26
+ ```
27
+
28
+ ```ts
29
+ import { KTComponents } from '@keenthemes/ktui';
30
+ import '@keenthemes/ktui/dist/styles.css';
31
+ KTComponents.init();
32
+ ```
33
+
34
+ ---
35
+
36
+ ## 2. Initialization
37
+
38
+ > **See the `ktui-install` skill** for framework-specific init patterns, SSR safety, and dynamic content handling.
39
+
40
+ ```ts
41
+ // Global init
42
+ KTComponents.init();
43
+
44
+ // Per-component re-init after dynamic content
45
+ import { KTModal } from '@keenthemes/ktui';
46
+ KTModal.init();
47
+ ```
48
+
49
+ ### Livewire SPA support
50
+
51
+ KtUI automatically re-initializes components on `livewire:navigate` events for seamless Laravel Livewire SPA navigation. No manual setup required.
52
+
53
+ ---
54
+
55
+ ## 3. Data-Attribute API (Declarative)
56
+
57
+ KtUI uses `data-kt-*` attributes for declarative wiring. This is the primary way to add behavior without writing JS.
58
+
59
+ ### Naming convention
60
+
61
+ | Attribute | Purpose |
62
+ |-----------|---------|
63
+ | `data-kt-{component}` | Marks the root element (triggers instance creation on init) |
64
+ | `data-kt-{component}-initialized` | Added automatically after init (don't set manually) |
65
+ | `data-kt-{component}-toggle` | Click target to toggle show/hide (value = CSS selector of target) |
66
+ | `data-kt-{component}-dismiss` | Click target to close/dismiss |
67
+ | `data-kt-{component}-{option}` | Config override via HTML attribute |
68
+
69
+ ### Example — Modal
70
+
71
+ ```html
72
+ <!-- Toggle button -->
73
+ <button data-kt-modal-toggle="#my-modal">Open Modal</button>
74
+
75
+ <!-- Modal root -->
76
+ <div data-kt-modal="true" id="my-modal">
77
+ <div class="kt-modal-content">
78
+ <h2>Hello</h2>
79
+ <button data-kt-modal-dismiss="true">Close</button>
80
+ </div>
81
+ </div>
82
+ ```
83
+
84
+ ### Example — Dropdown
85
+
86
+ ```html
87
+ <div data-kt-dropdown="true">
88
+ <button data-kt-dropdown-toggle="true">Menu</button>
89
+ <div data-kt-dropdown-menu="true" class="hidden">
90
+ <a data-kt-dropdown-item="true" href="#">Item 1</a>
91
+ <a data-kt-dropdown-item="true" href="#">Item 2</a>
92
+ </div>
93
+ </div>
94
+ ```
95
+
96
+ ### Config via data attributes
97
+
98
+ Any config option can be set as a data attribute using kebab-case with the `data-kt-{component}-` prefix:
99
+
100
+ ```html
101
+ <!-- JS config: { zindex: '100', backdrop: true, persistent: true } -->
102
+ <div data-kt-modal="true"
103
+ data-kt-modal-zindex="100"
104
+ data-kt-modal-backdrop="true"
105
+ data-kt-modal-persistent="true">
106
+ ```
107
+
108
+ ### Config via CSS custom properties
109
+
110
+ Config can also be overridden with CSS custom properties:
111
+
112
+ ```css
113
+ .my-modal {
114
+ --kt-modal-zindex: 200;
115
+ --kt-modal-backdrop: true;
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## 4. Component Programmatic API
122
+
123
+ Every component follows this pattern:
124
+
125
+ ```ts
126
+ // Get existing instance
127
+ const instance = KTModal.getInstance(element);
128
+
129
+ // Get or create
130
+ const instance = KTModal.getOrCreateInstance(element, config);
131
+
132
+ // Instance methods
133
+ instance.show();
134
+ instance.hide();
135
+ instance.toggle();
136
+ instance.isOpen();
137
+ instance.dispose();
138
+
139
+ // Events
140
+ const eventId = instance.on('show', (payload) => { /* ... */ });
141
+ instance.off('show', eventId);
142
+ ```
143
+
144
+ ### Instance management
145
+
146
+ | Static method | Returns |
147
+ |--------------|---------|
148
+ | `KTComponent.getInstance(el)` | Existing instance or `null` |
149
+ | `KTComponent.getOrCreateInstance(el, config?)` | Existing or new instance |
150
+ | `KTComponent.init()` | Scans DOM, creates instances, registers global handlers |
151
+
152
+ ### Event system
153
+
154
+ Events fire in two ways:
155
+
156
+ 1. **Callback registration** (via `on`/`off`):
157
+ ```ts
158
+ const id = modal.on('show', (payload) => {
159
+ if (payload.cancel) return; // cancelable events
160
+ console.log('showing');
161
+ });
162
+ modal.off('show', id);
163
+ ```
164
+
165
+ 2. **Custom DOM events** (bubbling, cancelable):
166
+ ```ts
167
+ element.addEventListener('show', (e) => {
168
+ console.log(e.detail.payload);
169
+ e.preventDefault(); // cancels the action
170
+ });
171
+ ```
172
+
173
+ **Event lifecycle** (most components):
174
+ - `toggle` → `show` → `shown` (after transition)
175
+ - `toggle` → `hide` → `hidden` (after transition)
176
+
177
+ Payload for cancelable events: `{ cancel: false }`. Set `cancel = true` to prevent the action.
178
+
179
+ ---
180
+
181
+ ## 5. Component Reference
182
+
183
+ ### Exported components from `@keenthemes/ktui`
184
+
185
+ | Component | Class | Root attribute |
186
+ |-----------|-------|---------------|
187
+ | Dropdown | `KTDropdown` | `data-kt-dropdown` |
188
+ | Context Menu | `KTContextMenu` | `data-kt-context-menu` |
189
+ | Modal | `KTModal` | `data-kt-modal` |
190
+ | Drawer | `KTDrawer` | `data-kt-drawer` |
191
+ | Collapse | `KTCollapse` | `data-kt-collapse` |
192
+ | Dismiss | `KTDismiss` | `data-kt-dismiss` |
193
+ | Tabs | `KTTabs` | `data-kt-tabs` |
194
+ | Accordion | `KTAccordion` | `data-kt-accordion` |
195
+ | Scrollspy | `KTScrollspy` | `data-kt-scrollspy` |
196
+ | Scrollable | `KTScrollable` | `data-kt-scrollable` |
197
+ | Scroll To | `KTScrollto` | `data-kt-scrollto` |
198
+ | Sticky | `KTSticky` | `data-kt-sticky` |
199
+ | Reparent | `KTReparent` | `data-kt-reparent` |
200
+ | Toggle | `KTToggle` | `data-kt-toggle` |
201
+ | Tooltip | `KTTooltip` | `data-kt-tooltip` |
202
+ | Stepper | `KTStepper` | `data-kt-stepper` |
203
+ | Theme Switch | `KTThemeSwitch` | `data-kt-theme-switch` |
204
+ | Image Input | `KTImageInput` | `data-kt-image-input` |
205
+ | Toggle Password | `KTTogglePassword` | `data-kt-toggle-password` |
206
+ | DataTable | `KTDataTable` | `data-kt-datatable` |
207
+ | Select | `KTSelect` | `data-kt-select` |
208
+ | Toast | `KTToast` | (static API, no root attr) |
209
+ | Rating | `KTRating` | `data-kt-rating` |
210
+ | Repeater | `KTRepeater` | `data-kt-repeater` |
211
+ | Clipboard | `KTClipboard` | `data-kt-clipboard` |
212
+ | Range Slider | `KTRangeSlider` | `data-kt-range-slider` |
213
+ | Pin Input | `KTPinInput` | `data-kt-pin-input` |
214
+ | Input Number | `KTInputNumber` | `data-kt-input-number` |
215
+ | Carousel | `KTCarousel` | `data-kt-carousel` |
216
+
217
+ ---
218
+
219
+ ## 6. Key Components — Detailed
220
+
221
+ ### 6.1 Modal (`KTModal`)
222
+
223
+ ```html
224
+ <button data-kt-modal-toggle="#myModal">Open</button>
225
+ <div id="myModal" data-kt-modal="true" class="hidden">
226
+ <div class="kt-modal-content">
227
+ <button data-kt-modal-dismiss="true">×</button>
228
+ <p>Content</p>
229
+ </div>
230
+ </div>
231
+ ```
232
+
233
+ **Config options:**
234
+
235
+ | Option | Type | Default | Description |
236
+ |--------|------|---------|-------------|
237
+ | `zindex` | string | `'90'` | Base z-index |
238
+ | `backdrop` | boolean | `true` | Show backdrop overlay |
239
+ | `backdropClass` | string | `'kt-modal-backdrop'` | Backdrop CSS class |
240
+ | `backdropStatic` | boolean | `false` | Static backdrop (no close on click) |
241
+ | `keyboard` | boolean | `true` | Close on Escape |
242
+ | `disableScroll` | boolean | `true` | Lock body scroll |
243
+ | `persistent` | boolean | `false` | Prevent close on outside click |
244
+ | `focus` | boolean | `true` | Auto-focus first `[data-kt-modal-input-focus]` |
245
+ | `hiddenClass` | string | `'hidden'` | Class to add when hidden |
246
+
247
+ **Events:** `toggle`, `show`, `shown`, `hide`, `hidden`
248
+
249
+ **Programmatic:**
250
+
251
+ ```ts
252
+ const modal = KTModal.getInstance(document.getElementById('myModal'));
253
+ modal.show();
254
+ modal.hide();
255
+ modal.isOpen(); // boolean
256
+ modal.getTargetElement(); // the toggle button that opened it
257
+ ```
258
+
259
+ **Auto-focus:** Add `data-kt-modal-input-focus` to an input inside the modal.
260
+
261
+ ### 6.2 Dropdown (`KTDropdown`)
262
+
263
+ Uses [Popper.js](https://popper.js.org/) for positioning.
264
+
265
+ ```html
266
+ <div data-kt-dropdown="true">
267
+ <button data-kt-dropdown-toggle="true">Click me</button>
268
+ <div data-kt-dropdown-menu="true" class="hidden">
269
+ <a data-kt-dropdown-item="true" href="#">Option 1</a>
270
+ <a data-kt-dropdown-item="true" href="#">Option 2</a>
271
+ </div>
272
+ </div>
273
+ ```
274
+
275
+ **Config options:**
276
+
277
+ | Option | Type | Default | Description |
278
+ |--------|------|---------|-------------|
279
+ | `trigger` | `'click'` \| `'hover'` | `'click'` | Open trigger |
280
+ | `placement` | string | `'bottom-start'` | Popper.js placement |
281
+ | `permanent` | boolean | `false` | Prevent auto-close |
282
+ | `dismiss` | boolean | `false` | Dismiss on item click |
283
+ | `zindex` | number | `105` | Dropdown z-index |
284
+ | `hoverTimeout` | number | `200` | Delay before close on hover (ms) |
285
+ | `offset` | string | `'0px, 5px'` | Popper offset `[skidding, distance]` |
286
+ | `container` | string | `''` | Move menu to container (e.g. `'body'`) |
287
+ | `keyboard` | boolean | `true` | Keyboard navigation |
288
+
289
+ **Events:** `show`, `shown`, `hide`, `hidden`
290
+
291
+ **Programmatic:**
292
+
293
+ ```ts
294
+ const dd = KTDropdown.getInstance(el);
295
+ dd.show();
296
+ dd.hide();
297
+ dd.toggle();
298
+ dd.isOpen();
299
+ dd.disable(); // prevent interaction
300
+ dd.enable();
301
+ ```
302
+
303
+ ### 6.3 Drawer (`KTDrawer`)
304
+
305
+ Similar to Modal but slides from an edge.
306
+
307
+ ```html
308
+ <button data-kt-drawer-toggle="#myDrawer">Open Drawer</button>
309
+ <div id="myDrawer" data-kt-drawer="true" class="hidden">
310
+ <div class="kt-drawer-content">
311
+ <button data-kt-drawer-dismiss="true">×</button>
312
+ <p>Drawer content</p>
313
+ </div>
314
+ </div>
315
+ ```
316
+
317
+ ### 6.4 Collapse / Accordion
318
+
319
+ ```html
320
+ <button data-kt-collapse-toggle="#myCollapse">Toggle</button>
321
+ <div id="myCollapse" data-kt-collapse="true" class="hidden">
322
+ Collapsed content
323
+ </div>
324
+ ```
325
+
326
+ Accordion groups multiple collapses — only one open at a time.
327
+
328
+ ### 6.5 Tabs (`KTTabs`)
329
+
330
+ ```html
331
+ <div data-kt-tabs="true">
332
+ <div data-kt-tabs-toggle="true" data-kt-tab="#tab1">Tab 1</div>
333
+ <div data-kt-tabs-toggle="true" data-kt-tab="#tab2">Tab 2</div>
334
+ </div>
335
+ <div id="tab1">Content 1</div>
336
+ <div id="tab2" class="hidden">Content 2</div>
337
+ ```
338
+
339
+ ### 6.6 Tooltip (`KTTooltip`)
340
+
341
+ ```html
342
+ <button data-kt-tooltip="true" data-kt-tooltip-content="Hello!">
343
+ Hover me
344
+ </button>
345
+ ```
346
+
347
+ ### 6.7 Toast (`KTToast`) — Static API
348
+
349
+ Toast is unique: **it uses a static API**, not instance-based.
350
+
351
+ ```ts
352
+ import { KTToast } from '@keenthemes/ktui';
353
+
354
+ // Basic usage
355
+ KTToast.show({ message: 'Saved!', variant: 'success' });
356
+
357
+ // Full options
358
+ KTToast.show({
359
+ message: 'Item deleted',
360
+ variant: 'error',
361
+ appearance: 'solid', // 'solid' | 'outline' | 'light'
362
+ size: 'md', // 'sm' | 'md' | 'lg'
363
+ position: 'top-end', // 'top-end' | 'top-center' | 'top-start' |
364
+ // 'bottom-end' | 'bottom-center' | 'bottom-start' |
365
+ // 'middle-end' | 'middle-center' | 'middle-start'
366
+ duration: 5000, // ms, auto-dismiss
367
+ important: false, // if true, no auto-dismiss
368
+ progress: true, // show progress bar
369
+ pauseOnHover: true, // pause timer on hover
370
+ dismiss: true, // show close button
371
+ icon: '<svg>...</svg>', // leading icon HTML
372
+ action: {
373
+ label: 'Undo',
374
+ onClick: (id) => { /* ... */ },
375
+ className: 'btn btn-sm',
376
+ },
377
+ cancel: {
378
+ label: 'Cancel',
379
+ onClick: (id) => { /* ... */ },
380
+ },
381
+ beep: true, // play notification sound
382
+ onAutoClose: (id) => {},
383
+ onDismiss: (id) => {},
384
+ });
385
+
386
+ // Global config
387
+ KTToast.config({
388
+ position: 'bottom-end',
389
+ duration: 4000,
390
+ maxToasts: 5,
391
+ offset: 15,
392
+ gap: 10,
393
+ });
394
+ ```
395
+
396
+ **Variants:** `info`, `success`, `error`, `warning`, `primary`, `secondary`, `destructive`, `mono`
397
+
398
+ **Custom content:**
399
+
400
+ ```ts
401
+ KTToast.show({
402
+ content: document.getElementById('my-toast-template'),
403
+ // or: content: () => document.createElement('div'),
404
+ // or: content: '<div>HTML string</div>',
405
+ });
406
+ ```
407
+
408
+ ### 6.8 DataTable (`KTDataTable`)
409
+
410
+ > **Full reference: see the `ktui-datatable` skill** for architecture, lifecycle, events, filters, fixed layouts, pitfalls, and build/testing.
411
+
412
+ Supports **local data** and **remote API** modes. Config: `apiEndpoint`, `pageSize`, `stateSave`, `columns` (render, checkbox, sortType, sortValue, createdCell), `sort`, `search`, `pagination`, `checkbox`, `lockedLayout`, `tableLayout`, `filter`.
413
+
414
+ Methods: `sort()`, `goPage()`, `setPageSize()`, `search()`, `setFilter()`, `reload()`, `redraw()`, `getState()`, `check()`, `uncheck()`, `getChecked()`.
415
+
416
+ ### 6.9 Select (`KTSelect`)
417
+
418
+ > **Full reference: see the `ktui-select` skill** for features, remote data, tags, combobox, events, keyboard navigation, and pitfalls.
419
+
420
+ Replaces native `<select>` with rich, searchable dropdown. Key features: `enable-search`, `tags`, `combobox`, `remote` (with URL), `pagination`, `select-all`, `placeholder`.
421
+
422
+ Events dispatched on both element AND document: `show`, `close`, `change`, `enabled`, `disabled`, `updated`, `reloadStart`, `reloadComplete`, `reloadError`. Also namespaced: `kt-select:change`, `kt-select:show`, etc.
423
+
424
+ Global config: `KTSelect.config({ enableSearch: true, searchPlaceholder: '...' })`
425
+
426
+ ### 6.10 Input Number (`KTInputNumber`)
427
+
428
+ ```html
429
+ <input type="number"
430
+ data-kt-input-number="true"
431
+ data-kt-input-number-min="0"
432
+ data-kt-input-number-max="100"
433
+ data-kt-input-number-step="5" />
434
+ ```
435
+
436
+ ### 6.11 Range Slider (`KTRangeSlider`)
437
+
438
+ ```html
439
+ <input type="range"
440
+ data-kt-range-slider="true"
441
+ data-kt-range-slider-min="0"
442
+ data-kt-range-slider-max="100" />
443
+ ```
444
+
445
+ ### 6.12 Pin Input (`KTPinInput`)
446
+
447
+ ```html
448
+ <div data-kt-pin-input="true"
449
+ data-kt-pin-input-length="6">
450
+ </div>
451
+ ```
452
+
453
+ ### 6.13 Carousel (`KTCarousel`)
454
+
455
+ ```html
456
+ <div data-kt-carousel="true"
457
+ data-kt-carousel-infinite="true">
458
+ <div data-kt-carousel-item="true">Slide 1</div>
459
+ <div data-kt-carousel-item="true">Slide 2</div>
460
+ </div>
461
+ ```
462
+
463
+ ### 6.14 Clipboard (`KTClipboard`)
464
+
465
+ ```html
466
+ <button data-kt-clipboard="true"
467
+ data-kt-clipboard-target="#code-block">
468
+ Copy
469
+ </button>
470
+ <pre id="code-block">text to copy</pre>
471
+ ```
472
+
473
+ ### 6.15 Repeater (`KTRepeater`)
474
+
475
+ Dynamic form field groups — add/remove rows.
476
+
477
+ ```html
478
+ <div data-kt-repeater="true">
479
+ <div data-kt-repeater-item="true">
480
+ <input name="items[0][name]" />
481
+ <button data-kt-repeater-delete="true">×</button>
482
+ </div>
483
+ <button data-kt-repeater-add="true">+ Add</button>
484
+ </div>
485
+ ```
486
+
487
+ ### 6.16 Rating (`KTRating`)
488
+
489
+ ```html
490
+ <div data-kt-rating="true"
491
+ data-kt-rating-value="3"
492
+ data-kt-rating-max="5">
493
+ </div>
494
+ ```
495
+
496
+ ---
497
+
498
+ ## 7. Helpers (Internal, but useful to know)
499
+
500
+ ### `KTDom`
501
+
502
+ - `KTDom.getElement(el)` — resolve string selector or element
503
+ - `KTDom.getCssProp(el, prop)` — get computed CSS custom property
504
+ - `KTDom.getDataAttributes(el, prefix)` — extract `data-{prefix}-*` attributes as config object
505
+ - `KTDom.isRTL()` — check if document is RTL
506
+ - `KTDom.reflow(el)` — force reflow (used before class changes)
507
+ - `KTDom.transitionEnd(el, callback)` — listen for transition end
508
+ - `KTDom.getHighestZindex(el)` — find highest z-index in parent tree
509
+
510
+ ### `KTData`
511
+
512
+ - `KTData.set(el, key, value)` — store data on element (WeakMap-based)
513
+ - `KTData.get(el, key)` — retrieve stored data
514
+ - `KTData.has(el, key)` — check if data exists
515
+ - `KTData.remove(el, key)` — remove stored data
516
+
517
+ ### `KTEventHandler`
518
+
519
+ - `KTEventHandler.on(el, selector, eventType, handler)` — delegated event binding
520
+ - `KTEventHandler.off(el, eventId)` — remove delegated handler
521
+
522
+ ### `KTUtils`
523
+
524
+ - `KTUtils.geUID(prefix?)` — generate unique ID
525
+ - `KTUtils.stringToBoolean(str)` — parse string to boolean
526
+ - `KTUtils.camelReverseCase(str)` — `camelCase` → `kebab-case`
527
+
528
+ ---
529
+
530
+ ## 8. Global Configuration
531
+
532
+ ### Per-component static config
533
+
534
+ ```ts
535
+ // Set defaults for all future instances
536
+ KTSelect.config({ enableSearch: true });
537
+ KTToast.config({ position: 'bottom-end', duration: 5000 });
538
+ ```
539
+
540
+ ### Window-level global config
541
+
542
+ ```ts
543
+ window.KTGlobalComponentsConfig = {
544
+ modal: { zindex: '100' },
545
+ dropdown: { placement: 'bottom-end' },
546
+ };
547
+ ```
548
+
549
+ This is merged into every component's config (lowest priority).
550
+
551
+ ### Config merge priority (lowest → highest)
552
+
553
+ 1. `window.KTGlobalComponentsConfig[component]`
554
+ 2. Component class `_defaultConfig`
555
+ 3. Static `.config()` (per-component)
556
+ 4. `data-kt-{component}-*` HTML attributes
557
+ 5. `--kt-{component}-{option}` CSS custom properties
558
+ 6. Constructor `config` argument (highest)
559
+
560
+ ---
561
+
562
+ ## 9. Theming
563
+
564
+ ### CSS Variables
565
+
566
+ KtUI follows a Shadcn-inspired convention. Define in your Tailwind entry:
567
+
568
+ ```css
569
+ :root {
570
+ /* Surfaces */
571
+ --background: oklch(1 0 0);
572
+ --foreground: oklch(14.1% 0.005 285.823);
573
+ --card: oklch(1 0 0);
574
+ --card-foreground: oklch(14.1% 0.005 285.823);
575
+ --popover: oklch(1 0 0);
576
+ --popover-foreground: oklch(14.1% 0.005 285.823);
577
+
578
+ /* Brand */
579
+ --primary: oklch(62.3% 0.214 259.815);
580
+ --primary-foreground: oklch(1 0 0);
581
+ --secondary: oklch(96.7% 0.001 264.542);
582
+ --secondary-foreground: oklch(20.5% 0.002 285.823);
583
+
584
+ /* Muted / Accent */
585
+ --muted: oklch(96.7% 0.001 264.542);
586
+ --muted-foreground: oklch(55.6% 0.005 285.823);
587
+ --accent: oklch(96.7% 0.001 264.542);
588
+ --accent-foreground: oklch(20.5% 0.002 285.823);
589
+
590
+ /* Destructive */
591
+ --destructive: oklch(63.7% 0.237 25.331);
592
+ --destructive-foreground: oklch(1 0 0);
593
+
594
+ /* Borders */
595
+ --border: oklch(92% 0.004 264.531);
596
+ --input: oklch(92% 0.004 264.531);
597
+ --ring: oklch(62.3% 0.214 259.815);
598
+
599
+ /* Radius */
600
+ --radius: 0.5rem;
601
+ }
602
+ ```
603
+
604
+ ### Background/foreground convention
605
+
606
+ - Background colors **omit** the `-background` suffix: `bg-primary` uses `var(--primary)`
607
+ - Foreground colors use `-foreground`: `text-primary-foreground` uses `var(--primary-foreground)`
608
+
609
+ ### Semantic classes
610
+
611
+ Use KtUI utilities for consistency:
612
+
613
+ - `bg-background`, `text-foreground`
614
+ - `bg-primary`, `text-primary-foreground`
615
+ - `bg-card`, `text-card`
616
+ - `kt-btn`, `kt-card`, `kt-input`
617
+
618
+ ### Dark mode
619
+
620
+ > **See the `ktui-install` skill** for the full dark mode setup (Tailwind variant, CSS overrides).
621
+
622
+ Theme switch: Use `KTThemeSwitch` component or toggle `.dark` class on `<html>`.
623
+
624
+ ---
625
+
626
+ ## 10. RTL Support
627
+
628
+ KtUI has built-in RTL support:
629
+
630
+ - `KTDom.isRTL()` checks `dir="rtl"` on `<html>`
631
+ - Dropdowns auto-switch placement (`placementRtl` config)
632
+ - Use logical properties in your CSS (`inset-inline-start` instead of `left`)
633
+
634
+ ---
635
+
636
+ ## 11. Common Pitfalls
637
+
638
+ | Problem | Cause | Fix |
639
+ |---------|-------|-----|
640
+ | Components not working | `init()` not called or called before DOM ready | Call `KTComponents.init()` after DOM is ready |
641
+ | Dropdown/Modal not opening | Missing `data-kt-*-toggle` attribute | Ensure toggle attribute value is a valid CSS selector |
642
+ | Styles missing | KtUI CSS or variables not loaded | Import `styles.css` and define CSS variables |
643
+ | SSR hydration errors | `init()` called on server | Guard: `if (typeof window !== 'undefined')` |
644
+ | Re-init not working | Existing instance blocks re-init | Call `dispose()` first, or use `getOrCreateInstance()` |
645
+ | DataTable not sorting | Missing `data-kt-datatable-column` on `<th>` | Add column attribute to each header cell |
646
+ | Select not searchable | Missing `data-kt-select-enable-search` | Add the attribute to the `<select>` element |
647
+ | Toast not appearing | No container created | Toast auto-creates containers; check z-index conflicts |
648
+ | Popper positioning wrong | Container not in DOM or overflow hidden | Use `data-kt-dropdown-container="body"` to portal |
649
+ | Dynamic content not interactive | `init()` not re-called after DOM mutation | Call `KTComponents.init()` or per-component init after adding markup |
650
+ | `getInstance()` returns null | Element not initialized | Use `getOrCreateInstance()` or ensure `init()` was called |
651
+
652
+ ---
653
+
654
+ ## 12. Source Code Structure
655
+
656
+ ```
657
+ ktui/src/
658
+ ├── index.ts # Main exports + KTComponents.init()
659
+ ├── init-all.ts # Auto-init on DOMContentLoaded
660
+ ├── types.ts # Shared types (KTOptionType, etc.)
661
+ ├── legacy.ts # Legacy compatibility
662
+ ├── helpers/
663
+ │ ├── dom.ts # DOM utilities (KTDom)
664
+ │ ├── data.ts # WeakMap data store (KTData)
665
+ │ ├── event-handler.ts # Delegated events (KTEventHandler)
666
+ │ └── utils.ts # General utilities (KTUtils)
667
+ └── components/
668
+ ├── component.ts # Base class (KTComponent)
669
+ ├── accordion/
670
+ ├── carousel/
671
+ ├── clipboard/
672
+ ├── collapse/
673
+ ├── context-menu/
674
+ ├── datatable/ # Complex — has local/remote providers, sort, search, pagination
675
+ ├── dismiss/
676
+ ├── drawer/
677
+ ├── dropdown/ # Uses @popperjs/core
678
+ ├── image-input/
679
+ ├── input-number/
680
+ ├── modal/
681
+ ├── pin-input/
682
+ ├── range-slider/
683
+ ├── rating/
684
+ ├── repeater/
685
+ ├── reparent/
686
+ ├── scrollable/
687
+ ├── scrollspy/
688
+ ├── scrollto/
689
+ ├── select/ # Complex — has search, remote, tags, combobox modules
690
+ ├── sticky/
691
+ ├── stepper/
692
+ ├── tabs/
693
+ ├── theme-switch/
694
+ ├── toast/ # Static API
695
+ ├── toggle/
696
+ ├── toggle-password/
697
+ └── tooltip/
698
+ ```
699
+
700
+ ---
701
+
702
+ ## 13. Documentation Links
703
+
704
+ - **Home:** [ktui.io](https://ktui.io)
705
+ - **Installation:** [ktui.io/docs/installation](https://ktui.io/docs/installation)
706
+ - **Theming:** [ktui.io/docs/theming](https://ktui.io/docs/theming)
707
+ - **Dark Mode:** [ktui.io/docs/dark-mode](https://ktui.io/docs/dark-mode)
708
+ - **TypeScript:** [ktui.io/docs/typescript](https://ktui.io/docs/typescript)
709
+ - **RTL:** [ktui.io/docs/rtl](https://ktui.io/docs/rtl)
710
+ - **Changelog:** [ktui.io/docs/changelog](https://ktui.io/docs/changelog)
711
+ - **Components:** `ktui.io/docs/{component}` (e.g. `ktui.io/docs/modal`, `ktui.io/docs/datatable`, `ktui.io/docs/select`)