ketekny-ui-kit
ketekny-ui-kit
Vue 3 UI component library with Tailwind CSS styling and utility plugins.
Requirements
vue:^3.0.0(peer dependency)- Tailwind CSS 3 build pipeline in your app (
tailwindcss,postcss,autoprefixer) - This package is built and tested against Tailwind CSS 3.x; Tailwind CSS 4 is not supported by the current setup
Consumer Dependencies
Install these in the consuming app:
npm install vue @lucide/vue class-variance-authority clsx dayjs element-plus moment reka-ui simple-code-editor tailwind-merge vue-router vue3-easy-data-table
If the app does not already include Tailwind CSS 3:
npm install -D tailwindcss@^3 postcss autoprefixer
Installation
Needed packages (install what is missing)
npm install ketekny-ui-kit
Quick Start
In your app entry (main.js / main.ts):
import { createApp } from "vue";
import App from "./App.vue";
import "ketekny-ui-kit/styles.css";
import {
kButton,
kInput,
kRange,
kSelect,
kDateSelector,
kCommandMenu,
kToggle,
kCheckbox,
kPage,
twoColLayout,
toastPlugin,
confirmPlugin,
alertPlugin,
inputDialogPlugin,
tooltipPlugin,
} from "ketekny-ui-kit";
const app = createApp(App);
app.component("kButton", kButton);
app.component("kInput", kInput);
app.component("kRange", kRange);
app.component("kSelect", kSelect);
app.component("kDateSelector", kDateSelector);
app.component("kToggle", kToggle);
app.component("kCheckbox", kCheckbox);
app.component("kPage", kPage);
app.component("twoColLayout", twoColLayout);
app.component("kCommandMenu", kCommandMenu);
app.use(toastPlugin);
app.use(confirmPlugin);
app.use(alertPlugin);
app.use(inputDialogPlugin);
app.use(tooltipPlugin);
app.mount("#app");
Example component usage:
<template>
<div class="p-6 space-y-3">
<kInput v-model="name" label="Name" />
<kButton label="Save" success @click="save" />
</div>
</template>
<script setup>
import { ref } from "vue";
const name = ref("");
function save() {
console.log("Saved:", name.value);
}
</script>
kCommandMenu is a presentation wrapper. The parent owns the categories and results through slots, while the menu exposes the current query and an onEntryClick helper:
<kCommandMenu
v-model:visible="menuVisible"
v-model:query="query"
@on-entry-click="openResult"
>
<template #categories="{ query }">
<!-- category controls -->
</template>
<template #list="{ query, onEntryClick }">
<button v-for="entry in entries" :key="entry.id" @click="onEntryClick(entry)">
{{ entry.title }}
</button>
</template>
</kCommandMenu>
The update event emits the query after it reaches minSearchLength (default 3), and emits an empty string when the query is cleared.
By default, kCommandMenu renders a kSearch trigger. Use the trigger slot when another control should open the menu:
<kCommandMenu v-model:visible="menuVisible">
<template #trigger>
<kSearch placeholder="Search everything..." />
</template>
</kCommandMenu>
Two-column layout usage:
<template>
<twoColLayout
title="App title"
:main-menu="menu"
:account="account"
@select-menu="handleSelect"
>
<kPage app-title="Demo" page-title="Dashboard">
<div class="p-6">Page content</div>
</kPage>
</twoColLayout>
</template>
<script setup>
import { ref } from "vue";
import { kPage } from "ketekny-ui-kit";
const account = ref({
loggedIn: true,
firstName: "Demo",
lastName: "User",
email: "demo@ketekny.gr",
});
const menu = [
{ id: "dashboard", label: "Dashboard", icon: "LayoutDashboard" },
{
id: "reports",
label: "Reports",
icon: "BarChart3",
notification: { chip: "New", icon: "Sparkles", tone: "info" },
},
];
function handleSelect(id) {
console.log("Selected menu item:", id);
}
</script>
Main-menu items may show a notification icon, chip, or both. Use
notification: { icon, chip, tone }, where icon is a Lucide icon name and
tone is neutral, info, success, warning, or danger. The existing
badge field remains supported as a chip value; chip, notificationIcon,
and chipTone are also available as shorthand fields. Notifications remain
visible when the sidebar is collapsed.
Tailwind Setup
Use the provided preset to include semantic tokens and safelist patterns used by dynamic component classes.
This README assumes Tailwind CSS 3. The tailwind.config.js / tailwind.config.cjs examples below are the supported integration path for this kit.
tailwind.config.js (ESM):
import tailwindPreset from "ketekny-ui-kit/tailwind-preset.js";
/** @type {import('tailwindcss').Config} */
export default {
presets: [tailwindPreset],
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/ketekny-ui-kit/**/*.{vue,js,ts,jsx,tsx}",
],
};
tailwind.config.cjs (CommonJS):
const tailwindPreset = require("ketekny-ui-kit/tailwind-preset.js").default;
/** @type {import('tailwindcss').Config} */
module.exports = {
presets: [tailwindPreset],
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/ketekny-ui-kit/**/*.{vue,js,ts,jsx,tsx}",
],
};
Plugins
toastPlugin: adds$toast.success|error|warning|info|show(...)confirmPlugin: adds$confirm(options)alertPlugin: adds$alert.success|warning|error|info(...)inputDialogPlugin: adds$prompt(options)tooltipPlugin: registersv-tooltip
Plugin API (quick reference)
$toast.success(message, options?)$toast.error(message, options?)$toast.warning(message, options?)$toast.info(message, options?)$toast.show({ type?, message, duration?, ... })$confirm({ title?, message, onConfirm?, onCancel? })$alert.success(message)$alert.error(message)$alert.warning(message)$alert.info(message)$prompt({ title?, message?, placeholder?, onConfirm? })
Note: exact option keys may vary by component/plugin implementation version.
Integer Range
kRange is a dual-handle slider that selects two integers. Its v-model is a
two-item array in [from, to] order.
<template>
<kRange
v-model="range"
label="Allowed age"
:min="18"
:max="80"
:step="1"
/>
</template>
<script setup>
import { ref } from "vue";
import { kRange } from "ketekny-ui-kit";
const range = ref([25, 65]);
</script>
The configured minimum and maximum appear at the slider ends. Selected values appear below their handles.
Props:
modelValue(Number[], default[0, 100]): selected[from, to]integers.min(Number, default0): minimum selectable value.max(Number, default100): maximum selectable value.step(Number, default1): positive integer increment.label,info,error,id: standard field metadata.disabled: disables the slider.showStops: shows every step along the slider.showTooltip: shows handle tooltips while dragging.
Events:
update:modelValue: emitted while either handle moves.change: emitted when the selected range changes.
Exports
Components:
kMessage,kCode,kToolbar,kTable,kTabs,kChipkSpinner,kDatatable,kIcon,kMenu,kSkeletonkProgressBar,kPagination,kTree,kButton,kSelect,kUploaderkToggle,kCheckbox,kInput,kRange,kDateSelector,kEditorkSelectButton,kTags,kSearch,kArrayList,kList,kTextAreakDialog,kDrawerkAppHeader,kAppFooter,kAppMain,kHerokPage,Page,kSinglePage,kSingleColPage,kMultiColPage,kTwoColPage,twoColLayout,legacyTwoColLayout
Other exports:
toastPlugin,confirmPlugin,alertPlugin,tooltipPlugin,inputDialogPlugintailwindPreset
Common Issues
- Styles look missing:
- Confirm
import "ketekny-ui-kit/styles.css";is in your app entry file.
- Confirm
- Tailwind classes from the kit are not applied:
- Confirm
tailwind.configincludes./node_modules/ketekny-ui-kit/**/*.{vue,js,ts,jsx,tsx}incontent. - Confirm
presets: [tailwindPreset]is present.
- Confirm
- Date/time pickers fail to resolve
dayjs/plugin/customParseFormat.js:- Upgrade to
ketekny-ui-kit1.0.36or newer.
- Upgrade to
- Vue peer dependency warning:
- Install/update Vue 3 in your app:
npm install vue@^3.
- Install/update Vue 3 in your app:
- Dynamic semantic classes are purged:
- Keep the provided preset safelist patterns, or replicate them in your own Tailwind config.
Development
npm run dev
npm run build
npm run preview
License
ISC
Links
- Live demo/docs: https://ui.ketekny.gr
- npm: https://www.npmjs.com/package/ketekny-ui-kit