Tailwindcss Development
anonaddy/anonaddy
Always invoke when the user's message includes 'tailwind' in any form.
Comprehensive guide to KtUI (Keenthemes Tailwind UI) — components, theming, initialization, data-attribute API, event system, helpers, and common patterns.
$ npx skills add keenthemes/ktui --skill ktui -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install keenthemes/ktui ktui --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/keenthemes/ktui.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/ktui .claude/skills/ktui && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "ktui" agent skill from https://github.com/keenthemes/ktui/tree/main/skills/ktui into .claude/skills/ktui/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ktui", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/keenthemes/ktui/tree/main/skills/ktuiType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add keenthemes/ktui --skill ktui -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install keenthemes/ktui ktui --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/keenthemes/ktui.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/ktui .agents/skills/ktui && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "ktui" agent skill from https://github.com/keenthemes/ktui/tree/main/skills/ktui into .agents/skills/ktui/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ktui", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add keenthemes/ktui --skill ktui -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install keenthemes/ktui ktui --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/keenthemes/ktui.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/ktui .cursor/skills/ktui && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "ktui" agent skill from https://github.com/keenthemes/ktui/tree/main/skills/ktui into .cursor/skills/ktui/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ktui", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/keenthemes/ktui.git --path skills/ktui--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add keenthemes/ktui --skill ktui -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install keenthemes/ktui ktui --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/keenthemes/ktui.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/ktui .gemini/skills/ktui && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "ktui" agent skill from https://github.com/keenthemes/ktui/tree/main/skills/ktui into .gemini/skills/ktui/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ktui", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install keenthemes/ktui ktuiInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add keenthemes/ktui --skill ktui -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/keenthemes/ktui.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/ktui .github/skills/ktui && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "ktui" agent skill from https://github.com/keenthemes/ktui/tree/main/skills/ktui into .github/skills/ktui/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ktui", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add keenthemes/ktui --skill ktui -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install keenthemes/ktui ktui --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/keenthemes/ktui.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/ktui .opencode/skills/ktui && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "ktui" agent skill from https://github.com/keenthemes/ktui/tree/main/skills/ktui into .opencode/skills/ktui/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ktui", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
ktuiComprehensive guide to KtUI (Keenthemes Tailwind UI) — components, theming, initialization, data-attribute API, event system, helpers, and common patterns.
Ktui is an agent skill from keenthemes/ktui. Comprehensive guide to KtUI (Keenthemes Tailwind UI) — components, theming, initialization, data-attribute API, event system, helpers, and common patterns. Use this skill when building UI with KtUI, adding/customizing components, working with KtUI theming/colors/dark-mode, or when the user mentions KtUI, ktui, Keenthemes components, or Tailwind UI components from Keenthemes.
Its SKILL.md is about 5.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Frontend & Design, covering Theming and dark mode and CSS and styling. It works with Tailwind CSS. The repository describes itself as: Open-source collection of customizable UI components for Tailwind CSS and vanilla JavaScript. The licence is MIT.
12 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 74a8e60. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
npmFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
ktui.iopopper.js.orgFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Ktui loads about 5.4k tokens when it runs. Until then it costs about 96 tokens; SKILL.md has 1,193 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from keenthemes/ktui at commit 74a8e60, republished under its MIT licence (© keenthemes). 1,193 words, ~5,363 tokens.
.claude/skills/ktui/SKILL.md (or your agent's skills folder).KtUI is a free, open-source Tailwind CSS component library by Keenthemes.
Package: @keenthemes/ktui (npm).
Always prefer ktui.io docs and examples over guessing markup or options.
See the
ktui-installskill for full installation, Tailwind config, framework integration, SSR, dark mode setup, and troubleshooting.
npm install @keenthemes/ktuiimport { KTComponents } from '@keenthemes/ktui';
import '@keenthemes/ktui/dist/styles.css';
KTComponents.init();See the
ktui-installskill for framework-specific init patterns, SSR safety, and dynamic content handling.
// Global init
KTComponents.init();
// Per-component re-init after dynamic content
import { KTModal } from '@keenthemes/ktui';
KTModal.init();KtUI automatically re-initializes components on livewire:navigate events for seamless Laravel Livewire SPA navigation. No manual setup required.
KtUI uses data-kt-* attributes for declarative wiring. This is the primary way to add behavior without writing JS.
| Attribute | Purpose |
|---|---|
data-kt-{component} | Marks the root element (triggers instance creation on init) |
data-kt-{component}-initialized | Added automatically after init (don't set manually) |
data-kt-{component}-toggle | Click target to toggle show/hide (value = CSS selector of target) |
data-kt-{component}-dismiss | Click target to close/dismiss |
data-kt-{component}-{option} | Config override via HTML attribute |
<!-- Toggle button -->
<button data-kt-modal-toggle="#my-modal">Open Modal</button>
<!-- Modal root -->
<div data-kt-modal="true" id="my-modal">
<div class="kt-modal-content">
<h2>Hello</h2>
<button data-kt-modal-dismiss="true">Close</button>
</div>
</div><div data-kt-dropdown="true">
<button data-kt-dropdown-toggle="true">Menu</button>
<div data-kt-dropdown-menu="true" class="hidden">
<a data-kt-dropdown-item="true" href="#">Item 1</a>
<a data-kt-dropdown-item="true" href="#">Item 2</a>
</div>
</div>Any config option can be set as a data attribute using kebab-case with the data-kt-{component}- prefix:
<!-- JS config: { zindex: '100', backdrop: true, persistent: true } -->
<div data-kt-modal="true"
data-kt-modal-zindex="100"
data-kt-modal-backdrop="true"
data-kt-modal-persistent="true">Config can also be overridden with CSS custom properties:
.my-modal {
--kt-modal-zindex: 200;
--kt-modal-backdrop: true;
}Every component follows this pattern:
// Get existing instance
const instance = KTModal.getInstance(element);
// Get or create
const instance = KTModal.getOrCreateInstance(element, config);
// Instance methods
instance.show();
instance.hide();
instance.toggle();
instance.isOpen();
instance.dispose();
// Events
const eventId = instance.on('show', (payload) => { /* ... */ });
instance.off('show', eventId);| Static method | Returns |
|---|---|
KTComponent.getInstance(el) | Existing instance or null |
KTComponent.getOrCreateInstance(el, config?) | Existing or new instance |
KTComponent.init() | Scans DOM, creates instances, registers global handlers |
Events fire in two ways:
Callback registration (via on/off):
const id = modal.on('show', (payload) => {
if (payload.cancel) return; // cancelable events
console.log('showing');
});
modal.off('show', id);Custom DOM events (bubbling, cancelable):
element.addEventListener('show', (e) => {
console.log(e.detail.payload);
e.preventDefault(); // cancels the action
});Event lifecycle (most components):
toggle → show → shown (after transition)toggle → hide → hidden (after transition)Payload for cancelable events: { cancel: false }. Set cancel = true to prevent the action.
@keenthemes/ktui| Component | Class | Root attribute |
|---|---|---|
| Dropdown | KTDropdown | data-kt-dropdown |
| Context Menu | KTContextMenu | data-kt-context-menu |
| Modal | KTModal | data-kt-modal |
| Drawer | KTDrawer | data-kt-drawer |
| Collapse | KTCollapse | data-kt-collapse |
| Dismiss | KTDismiss | data-kt-dismiss |
| Tabs | KTTabs | data-kt-tabs |
| Accordion | KTAccordion | data-kt-accordion |
| Scrollspy | KTScrollspy | data-kt-scrollspy |
| Scrollable | KTScrollable | data-kt-scrollable |
| Scroll To | KTScrollto | data-kt-scrollto |
| Sticky | KTSticky | data-kt-sticky |
| Reparent | KTReparent | data-kt-reparent |
| Toggle | KTToggle | data-kt-toggle |
| Tooltip | KTTooltip | data-kt-tooltip |
| Stepper | KTStepper | data-kt-stepper |
| Theme Switch | KTThemeSwitch | data-kt-theme-switch |
| Image Input | KTImageInput | data-kt-image-input |
| Toggle Password | KTTogglePassword | data-kt-toggle-password |
| DataTable | KTDataTable | data-kt-datatable |
| Select | KTSelect | data-kt-select |
| Toast | KTToast | (static API, no root attr) |
| Rating | KTRating | data-kt-rating |
| Repeater | KTRepeater | data-kt-repeater |
| Clipboard | KTClipboard | data-kt-clipboard |
| Range Slider | KTRangeSlider | data-kt-range-slider |
| Pin Input | KTPinInput | data-kt-pin-input |
| Input Number | KTInputNumber | data-kt-input-number |
| Carousel | KTCarousel | data-kt-carousel |
KTModal)<button data-kt-modal-toggle="#myModal">Open</button>
<div id="myModal" data-kt-modal="true" class="hidden">
<div class="kt-modal-content">
<button data-kt-modal-dismiss="true">×</button>
<p>Content</p>
</div>
</div>Config options:
| Option | Type | Default | Description |
|---|---|---|---|
zindex | string | '90' | Base z-index |
backdrop | boolean | true | Show backdrop overlay |
backdropClass | string | 'kt-modal-backdrop' | Backdrop CSS class |
backdropStatic | boolean | false | Static backdrop (no close on click) |
keyboard | boolean | true | Close on Escape |
disableScroll | boolean | true | Lock body scroll |
persistent | boolean | false | Prevent close on outside click |
focus | boolean | true | Auto-focus first [data-kt-modal-input-focus] |
hiddenClass | string | 'hidden' | Class to add when hidden |
Events: toggle, show, shown, hide, hidden
Programmatic:
const modal = KTModal.getInstance(document.getElementById('myModal'));
modal.show();
modal.hide();
modal.isOpen(); // boolean
modal.getTargetElement(); // the toggle button that opened itAuto-focus: Add data-kt-modal-input-focus to an input inside the modal.
KTDropdown)Uses Popper.js for positioning.
<div data-kt-dropdown="true">
<button data-kt-dropdown-toggle="true">Click me</button>
<div data-kt-dropdown-menu="true" class="hidden">
<a data-kt-dropdown-item="true" href="#">Option 1</a>
<a data-kt-dropdown-item="true" href="#">Option 2</a>
</div>
</div>Config options:
| Option | Type | Default | Description |
|---|---|---|---|
trigger | 'click' | 'hover' | 'click' | Open trigger |
placement | string | 'bottom-start' | Popper.js placement |
permanent | boolean | false | Prevent auto-close |
dismiss | boolean | false | Dismiss on item click |
zindex | number | 105 | Dropdown z-index |
hoverTimeout | number | 200 | Delay before close on hover (ms) |
offset | string | '0px, 5px' | Popper offset [skidding, distance] |
container | string | '' | Move menu to container (e.g. 'body') |
keyboard | boolean | true | Keyboard navigation |
Events: show, shown, hide, hidden
Programmatic:
const dd = KTDropdown.getInstance(el);
dd.show();
dd.hide();
dd.toggle();
dd.isOpen();
dd.disable(); // prevent interaction
dd.enable();KTDrawer)Similar to Modal but slides from an edge.
<button data-kt-drawer-toggle="#myDrawer">Open Drawer</button>
<div id="myDrawer" data-kt-drawer="true" class="hidden">
<div class="kt-drawer-content">
<button data-kt-drawer-dismiss="true">×</button>
<p>Drawer content</p>
</div>
</div><button data-kt-collapse-toggle="#myCollapse">Toggle</button>
<div id="myCollapse" data-kt-collapse="true" class="hidden">
Collapsed content
</div>Accordion groups multiple collapses — only one open at a time.
KTTabs)<div data-kt-tabs="true">
<div data-kt-tabs-toggle="true" data-kt-tab="#tab1">Tab 1</div>
<div data-kt-tabs-toggle="true" data-kt-tab="#tab2">Tab 2</div>
</div>
<div id="tab1">Content 1</div>
<div id="tab2" class="hidden">Content 2</div>KTTooltip)<button data-kt-tooltip="true" data-kt-tooltip-content="Hello!">
Hover me
</button>KTToast) — Static APIToast is unique: it uses a static API, not instance-based.
import { KTToast } from '@keenthemes/ktui';
// Basic usage
KTToast.show({ message: 'Saved!', variant: 'success' });
// Full options
KTToast.show({
message: 'Item deleted',
variant: 'error',
appearance: 'solid', // 'solid' | 'outline' | 'light'
size: 'md', // 'sm' | 'md' | 'lg'
position: 'top-end', // 'top-end' | 'top-center' | 'top-start' |
// 'bottom-end' | 'bottom-center' | 'bottom-start' |
// 'middle-end' | 'middle-center' | 'middle-start'
duration: 5000, // ms, auto-dismiss
important: false, // if true, no auto-dismiss
progress: true, // show progress bar
pauseOnHover: true, // pause timer on hover
dismiss: true, // show close button
icon: '<svg>...</svg>', // leading icon HTML
action: {
label: 'Undo',
onClick: (id) => { /* ... */ },
className: 'btn btn-sm',
},
cancel: {
label: 'Cancel',
onClick: (id) => { /* ... */ },
},
beep: true, // play notification sound
onAutoClose: (id) => {},
onDismiss: (id) => {},
});
// Global config
KTToast.config({
position: 'bottom-end',
duration: 4000,
maxToasts: 5,
offset: 15,
gap: 10,
});Variants: info, success, error, warning, primary, secondary, destructive, mono
Custom content:
KTToast.show({
content: document.getElementById('my-toast-template'),
// or: content: () => document.createElement('div'),
// or: content: '<div>HTML string</div>',
});KTDataTable)Full reference: see the
ktui-datatableskill for architecture, lifecycle, events, filters, fixed layouts, pitfalls, and build/testing.
Supports local data and remote API modes. Config: apiEndpoint, pageSize, stateSave, columns (render, checkbox, sortType, sortValue, createdCell), sort, search, pagination, checkbox, lockedLayout, tableLayout, filter.
Methods: sort(), goPage(), setPageSize(), search(), setFilter(), reload(), redraw(), getState(), check(), uncheck(), getChecked().
KTSelect)Full reference: see the
ktui-selectskill for features, remote data, tags, combobox, events, keyboard navigation, and pitfalls.
Replaces native <select> with rich, searchable dropdown. Key features: enable-search, tags, combobox, remote (with URL), pagination, select-all, placeholder.
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.
Global config: KTSelect.config({ enableSearch: true, searchPlaceholder: '...' })
KTInputNumber)<input type="number"
data-kt-input-number="true"
data-kt-input-number-min="0"
data-kt-input-number-max="100"
data-kt-input-number-step="5" />KTRangeSlider)<input type="range"
data-kt-range-slider="true"
data-kt-range-slider-min="0"
data-kt-range-slider-max="100" />KTPinInput)<div data-kt-pin-input="true"
data-kt-pin-input-length="6">
</div>KTCarousel)<div data-kt-carousel="true"
data-kt-carousel-infinite="true">
<div data-kt-carousel-item="true">Slide 1</div>
<div data-kt-carousel-item="true">Slide 2</div>
</div>KTClipboard)<button data-kt-clipboard="true"
data-kt-clipboard-target="#code-block">
Copy
</button>
<pre id="code-block">text to copy</pre>KTRepeater)Dynamic form field groups — add/remove rows.
<div data-kt-repeater="true">
<div data-kt-repeater-item="true">
<input name="items[0][name]" />
<button data-kt-repeater-delete="true">×</button>
</div>
<button data-kt-repeater-add="true">+ Add</button>
</div>KTRating)<div data-kt-rating="true"
data-kt-rating-value="3"
data-kt-rating-max="5">
</div>KTDomKTDom.getElement(el) — resolve string selector or elementKTDom.getCssProp(el, prop) — get computed CSS custom propertyKTDom.getDataAttributes(el, prefix) — extract data-{prefix}-* attributes as config objectKTDom.isRTL() — check if document is RTLKTDom.reflow(el) — force reflow (used before class changes)KTDom.transitionEnd(el, callback) — listen for transition endKTDom.getHighestZindex(el) — find highest z-index in parent treeKTDataKTData.set(el, key, value) — store data on element (WeakMap-based)KTData.get(el, key) — retrieve stored dataKTData.has(el, key) — check if data existsKTData.remove(el, key) — remove stored dataKTEventHandlerKTEventHandler.on(el, selector, eventType, handler) — delegated event bindingKTEventHandler.off(el, eventId) — remove delegated handlerKTUtilsKTUtils.geUID(prefix?) — generate unique IDKTUtils.stringToBoolean(str) — parse string to booleanKTUtils.camelReverseCase(str) — camelCase → kebab-case// Set defaults for all future instances
KTSelect.config({ enableSearch: true });
KTToast.config({ position: 'bottom-end', duration: 5000 });window.KTGlobalComponentsConfig = {
modal: { zindex: '100' },
dropdown: { placement: 'bottom-end' },
};This is merged into every component's config (lowest priority).
window.KTGlobalComponentsConfig[component]_defaultConfig.config() (per-component)data-kt-{component}-* HTML attributes--kt-{component}-{option} CSS custom propertiesconfig argument (highest)KtUI follows a Shadcn-inspired convention. Define in your Tailwind entry:
:root {
/* Surfaces */
--background: oklch(1 0 0);
--foreground: oklch(14.1% 0.005 285.823);
--card: oklch(1 0 0);
--card-foreground: oklch(14.1% 0.005 285.823);
--popover: oklch(1 0 0);
--popover-foreground: oklch(14.1% 0.005 285.823);
/* Brand */
--primary: oklch(62.3% 0.214 259.815);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(96.7% 0.001 264.542);
--secondary-foreground: oklch(20.5% 0.002 285.823);
/* Muted / Accent */
--muted: oklch(96.7% 0.001 264.542);
--muted-foreground: oklch(55.6% 0.005 285.823);
--accent: oklch(96.7% 0.001 264.542);
--accent-foreground: oklch(20.5% 0.002 285.823);
/* Destructive */
--destructive: oklch(63.7% 0.237 25.331);
--destructive-foreground: oklch(1 0 0);
/* Borders */
--border: oklch(92% 0.004 264.531);
--input: oklch(92% 0.004 264.531);
--ring: oklch(62.3% 0.214 259.815);
/* Radius */
--radius: 0.5rem;
}-background suffix: bg-primary uses var(--primary)-foreground: text-primary-foreground uses var(--primary-foreground)Use KtUI utilities for consistency:
bg-background, text-foregroundbg-primary, text-primary-foregroundbg-card, text-cardkt-btn, kt-card, kt-inputSee the
ktui-installskill for the full dark mode setup (Tailwind variant, CSS overrides).
Theme switch: Use KTThemeSwitch component or toggle .dark class on <html>.
KtUI has built-in RTL support:
KTDom.isRTL() checks dir="rtl" on <html>placementRtl config)inset-inline-start instead of left)| Problem | Cause | Fix |
|---|---|---|
| Components not working | init() not called or called before DOM ready | Call KTComponents.init() after DOM is ready |
| Dropdown/Modal not opening | Missing data-kt-*-toggle attribute | Ensure toggle attribute value is a valid CSS selector |
| Styles missing | KtUI CSS or variables not loaded | Import styles.css and define CSS variables |
| SSR hydration errors | init() called on server | Guard: if (typeof window !== 'undefined') |
| Re-init not working | Existing instance blocks re-init | Call dispose() first, or use getOrCreateInstance() |
| DataTable not sorting | Missing data-kt-datatable-column on <th> | Add column attribute to each header cell |
| Select not searchable | Missing data-kt-select-enable-search | Add the attribute to the <select> element |
| Toast not appearing | No container created | Toast auto-creates containers; check z-index conflicts |
| Popper positioning wrong | Container not in DOM or overflow hidden | Use data-kt-dropdown-container="body" to portal |
| Dynamic content not interactive | init() not re-called after DOM mutation | Call KTComponents.init() or per-component init after adding markup |
getInstance() returns null | Element not initialized | Use getOrCreateInstance() or ensure init() was called |
ktui/src/
├── index.ts # Main exports + KTComponents.init()
├── init-all.ts # Auto-init on DOMContentLoaded
├── types.ts # Shared types (KTOptionType, etc.)
├── legacy.ts # Legacy compatibility
├── helpers/
│ ├── dom.ts # DOM utilities (KTDom)
│ ├── data.ts # WeakMap data store (KTData)
│ ├── event-handler.ts # Delegated events (KTEventHandler)
│ └── utils.ts # General utilities (KTUtils)
└── components/
├── component.ts # Base class (KTComponent)
├── accordion/
├── carousel/
├── clipboard/
├── collapse/
├── context-menu/
├── datatable/ # Complex — has local/remote providers, sort, search, pagination
├── dismiss/
├── drawer/
├── dropdown/ # Uses @popperjs/core
├── image-input/
├── input-number/
├── modal/
├── pin-input/
├── range-slider/
├── rating/
├── repeater/
├── reparent/
├── scrollable/
├── scrollspy/
├── scrollto/
├── select/ # Complex — has search, remote, tags, combobox modules
├── sticky/
├── stepper/
├── tabs/
├── theme-switch/
├── toast/ # Static API
├── toggle/
├── toggle-password/
└── tooltip/ktui.io/docs/{component} (e.g. ktui.io/docs/modal, ktui.io/docs/datatable, ktui.io/docs/select)© keenthemes, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/ktui of keenthemes/ktui.
Open the folder on GitHubat commit 74a8e60
Ktui next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Ktui this skillkeenthemes/ktui | 151 | — | ~5.4k | Automated safety check: Pass | MIT | |
| Tailwindcss Developmentanonaddy/anonaddy | 4.9k | 10 repos | ~865 | Automated safety check: Pass | MIT | |
| UI StylingOhh-889/skyroc | 795 | 13 repos | ~2.5k | Automated safety check: Pass | MIT | |
| MCP Developmentcoollabsio/coolify | 63k | 1 repos | ~949 | Automated safety check: Pass | MIT | |
| DaisyUI 5 Color Rulessaadeghi/daisyui | 43k | — | ~1.7k | Automated safety check: Pass | MIT | |
| Tailwind Theme Builderjezweb/claude-skills | 1.1k | 1 repos | ~3.2k | Automated safety check: Pass | MIT |
anonaddy/anonaddy
Always invoke when the user's message includes 'tailwind' in any form.
Ohh-889/skyroc
Create beautiful, accessible user interfaces with shadcn/ui components (built on Radix UI + Tailwind), Tailwind CSS utility-first styling, and canvas-based visual designs.
coollabsio/coolify
A skill your agent uses for Laravel MCP development. An agent skill from coollabsio/coolify.
saadeghi/daisyui
Rules for using daisyUI 5's semantic color names, such as primary and base-100, so interfaces stay readable across themes.
jezweb/claude-skills
Set up Tailwind v4 + shadcn/ui themed UI with dark mode. An agent skill from jezweb/claude-skills.
leepokai/Codync
Guide to Sonner, the React toast library — install and wire up the Toaster, pick the right toast() call, promise and loading toasts, updating, dismissing and persisting toasts, styling, theming and…
keenthemes/ktui
KtUI DataTable (KTDataTable) — local/remote data, sorting, filtering, pagination, checkbox selection, state persistence, fixed layouts, event system, and architecture.
keenthemes/ktui
Install, configure, and initialize KtUI (Keenthemes Tailwind UI) in any project.
keenthemes/ktui
KtUI Select (KTSelect) — rich searchable multi-select dropdown replacing native select.
Works with
Categories
Comprehensive guide to KtUI (Keenthemes Tailwind UI) — components, theming, initialization, data-attribute API, event system, helpers, and common patterns. Ktui is an agent skill from keenthemes/ktui. Comprehensive guide to KtUI (Keenthemes Tailwind UI) — components, theming, initialization, data-attribute API, event system, helpers, and common patterns.
Ktui fits situations like: building UI with KtUI; adding/customizing components; working with KtUI theming/colors/dark-mode; the user mentions KtUI.
Run `npx skills add keenthemes/ktui --skill ktui -a claude-code`. Or copy the skill folder (skills/ktui in keenthemes/ktui) into .claude/skills/ktui in your project. Claude Code loads it when a task matches its description.
Run `npx skills add keenthemes/ktui --skill ktui -a codex`. Or copy the skill folder (skills/ktui in keenthemes/ktui) into .agents/skills/ktui in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add keenthemes/ktui --skill ktui -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ktui, .gemini/skills/ktui, .github/skills/ktui and .opencode/skills/ktui in your project.
Going by SKILL.md and its folder, Ktui needs the command-line tools its instructions call (npm). Our summary lists: Node.js.
SKILL.md names 2 domains. As links in the text: ktui.io and popper.js.org. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Ktui is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.4k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Ktui: Tailwindcss Development (anonaddy/anonaddy, 4.9k stars), UI Styling (Ohh-889/skyroc, 795 stars), MCP Development (coollabsio/coolify, 63k stars) and DaisyUI 5 Color Rules (saadeghi/daisyui, 43k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
keenthemes (a GitHub organization) maintains it in keenthemes/ktui, which has 151 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on June 17, 2026.
Source: keenthemes/ktui on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.