ketekny-ui-kit 1.0.91 → 1.0.93
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.
- package/README.md +41 -1
- package/index.js +3 -2
- package/package.json +1 -1
- package/src/twoColLayout/components/MultilevelSidebar.vue +57 -3
- package/src/twoColLayout/components/TwoColLayout.vue +5 -0
- package/src/ui/componentDescription.vue +10 -10
- package/src/ui/componentShowcase.vue +7 -7
- package/src/ui/kCode.vue +2 -2
- package/src/ui/themes/kButton.theme.js +2 -2
package/README.md
CHANGED
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
kDateSelector,
|
|
47
47
|
kToggle,
|
|
48
48
|
kCheckbox,
|
|
49
|
+
twoColLayout,
|
|
49
50
|
toastPlugin,
|
|
50
51
|
confirmPlugin,
|
|
51
52
|
alertPlugin,
|
|
@@ -61,6 +62,7 @@ app.component("kSelect", kSelect);
|
|
|
61
62
|
app.component("kDateSelector", kDateSelector);
|
|
62
63
|
app.component("kToggle", kToggle);
|
|
63
64
|
app.component("kCheckbox", kCheckbox);
|
|
65
|
+
app.component("twoColLayout", twoColLayout);
|
|
64
66
|
|
|
65
67
|
app.use(toastPlugin);
|
|
66
68
|
app.use(confirmPlugin);
|
|
@@ -92,6 +94,44 @@ function save() {
|
|
|
92
94
|
</script>
|
|
93
95
|
```
|
|
94
96
|
|
|
97
|
+
Two-column layout usage:
|
|
98
|
+
|
|
99
|
+
```vue
|
|
100
|
+
<template>
|
|
101
|
+
<twoColLayout
|
|
102
|
+
title="App title"
|
|
103
|
+
:main-menu="menu"
|
|
104
|
+
:account="account"
|
|
105
|
+
@select-menu="handleSelect"
|
|
106
|
+
>
|
|
107
|
+
<kSingleColPage app-title="Demo" page-title="Dashboard">
|
|
108
|
+
<div class="p-6">Page content</div>
|
|
109
|
+
</kSingleColPage>
|
|
110
|
+
</twoColLayout>
|
|
111
|
+
</template>
|
|
112
|
+
|
|
113
|
+
<script setup>
|
|
114
|
+
import { ref } from "vue";
|
|
115
|
+
import { kSingleColPage } from "ketekny-ui-kit";
|
|
116
|
+
|
|
117
|
+
const account = ref({
|
|
118
|
+
loggedIn: true,
|
|
119
|
+
firstName: "Demo",
|
|
120
|
+
lastName: "User",
|
|
121
|
+
email: "demo@ketekny.gr",
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const menu = [
|
|
125
|
+
{ id: "dashboard", label: "Dashboard", icon: "LayoutDashboard" },
|
|
126
|
+
{ id: "reports", label: "Reports", icon: "BarChart3" },
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
function handleSelect(id) {
|
|
130
|
+
console.log("Selected menu item:", id);
|
|
131
|
+
}
|
|
132
|
+
</script>
|
|
133
|
+
```
|
|
134
|
+
|
|
95
135
|
## Tailwind Setup
|
|
96
136
|
|
|
97
137
|
Use the provided preset to include semantic tokens and safelist patterns used by dynamic component classes.
|
|
@@ -165,6 +205,7 @@ Components:
|
|
|
165
205
|
- `kSelectButton`, `kTags`, `kSearch`, `kArrayList`, `kList`, `kTextArea`
|
|
166
206
|
- `kDialog`, `kDrawer`
|
|
167
207
|
- `kAppHeader`, `kAppFooter`, `kAppMain`, `kHero`
|
|
208
|
+
- `kSingleColPage`, `kTwoColPage`, `twoColLayout`, `legacyTwoColLayout`
|
|
168
209
|
|
|
169
210
|
Other exports:
|
|
170
211
|
|
|
@@ -202,4 +243,3 @@ ISC
|
|
|
202
243
|
- Live demo/docs: https://ui.ketekny.gr
|
|
203
244
|
- npm: https://www.npmjs.com/package/ketekny-ui-kit
|
|
204
245
|
|
|
205
|
-
|
package/index.js
CHANGED
|
@@ -38,7 +38,8 @@ import kAppMain from './src/layout/kAppMain.vue'
|
|
|
38
38
|
import kHero from './src/layout/kHero.vue'
|
|
39
39
|
import kSingleColPage from './src/layout/kSingleColPage.vue'
|
|
40
40
|
import kTwoColPage from './src/layout/kTwoColPage.vue'
|
|
41
|
-
import twoColLayout from './src/
|
|
41
|
+
import twoColLayout from './src/twoColLayout/components/TwoColLayout.vue'
|
|
42
|
+
import legacyTwoColLayout from './src/layout/twoColLayout.vue'
|
|
42
43
|
|
|
43
44
|
// Toast/Confirm/Alert Plugins
|
|
44
45
|
import toastPlugin from './src/plugins/toastPlugin.js'
|
|
@@ -62,7 +63,7 @@ export {
|
|
|
62
63
|
kDialog, kDrawer,
|
|
63
64
|
|
|
64
65
|
// Layout Components
|
|
65
|
-
kAppHeader, kAppFooter, kAppMain, kHero, kSingleColPage, kTwoColPage, twoColLayout,
|
|
66
|
+
kAppHeader, kAppFooter, kAppMain, kHero, kSingleColPage, kTwoColPage, twoColLayout, legacyTwoColLayout,
|
|
66
67
|
|
|
67
68
|
// Plugins
|
|
68
69
|
toastPlugin, confirmPlugin, alertPlugin, tooltipPlugin, inputDialogPlugin,
|
package/package.json
CHANGED
|
@@ -33,6 +33,10 @@ export default {
|
|
|
33
33
|
type: String,
|
|
34
34
|
default: "",
|
|
35
35
|
},
|
|
36
|
+
appIcon: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: "",
|
|
39
|
+
},
|
|
36
40
|
width: {
|
|
37
41
|
type: String,
|
|
38
42
|
default: "360px",
|
|
@@ -65,7 +69,7 @@ export default {
|
|
|
65
69
|
emits: ['select', 'logo-click', 'signin', 'signup', 'signout', 'edit-profile', 'item-click'],
|
|
66
70
|
data() {
|
|
67
71
|
return {
|
|
68
|
-
activeId: '
|
|
72
|
+
activeId: '',
|
|
69
73
|
query: '',
|
|
70
74
|
collapsed: false,
|
|
71
75
|
openIds: new Set(['projects']),
|
|
@@ -115,7 +119,49 @@ export default {
|
|
|
115
119
|
return all
|
|
116
120
|
},
|
|
117
121
|
},
|
|
122
|
+
watch: {
|
|
123
|
+
mainMenu: {
|
|
124
|
+
handler() {
|
|
125
|
+
this.syncActiveFromMenu()
|
|
126
|
+
},
|
|
127
|
+
deep: true,
|
|
128
|
+
immediate: true,
|
|
129
|
+
},
|
|
130
|
+
$route() {
|
|
131
|
+
this.syncActiveFromMenu()
|
|
132
|
+
},
|
|
133
|
+
},
|
|
118
134
|
methods: {
|
|
135
|
+
syncActiveFromMenu() {
|
|
136
|
+
const routePath = this.$route?.path
|
|
137
|
+
const findMatch = (items, parentIds = []) => {
|
|
138
|
+
for (const item of items) {
|
|
139
|
+
const itemPath = item?.link?.to ?? item?.to ?? null
|
|
140
|
+
if (routePath && itemPath === routePath) {
|
|
141
|
+
return {
|
|
142
|
+
id: item.id,
|
|
143
|
+
parentIds,
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (item?.children?.length) {
|
|
147
|
+
const childMatch = findMatch(item.children, [...parentIds, item.id])
|
|
148
|
+
if (childMatch) return childMatch
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return null
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const matched = findMatch(this.mainMenu)
|
|
155
|
+
if (matched?.id) {
|
|
156
|
+
this.activeId = matched.id
|
|
157
|
+
this.openIds = new Set([...this.openIds, ...matched.parentIds])
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!this.activeId && this.mainMenu[0]?.id) {
|
|
162
|
+
this.activeId = this.mainMenu[0].id
|
|
163
|
+
}
|
|
164
|
+
},
|
|
119
165
|
toggleCollapsed() {
|
|
120
166
|
this.collapsed = !this.collapsed
|
|
121
167
|
},
|
|
@@ -225,12 +271,20 @@ export default {
|
|
|
225
271
|
</p>
|
|
226
272
|
</div>
|
|
227
273
|
|
|
228
|
-
<div v-else-if="title && collapsed" class="px-3 pb-2">
|
|
274
|
+
<div v-else-if="(title || appIcon) && collapsed" class="flex justify-center px-3 pb-2">
|
|
229
275
|
<div
|
|
230
276
|
v-tooltip.right="title"
|
|
231
277
|
class="flex h-10 w-10 items-center justify-center rounded-md border border-sidebar-border/30 bg-sidebar-accent/30 text-[10px] font-bold tracking-[0.18em] text-sidebar-muted"
|
|
232
278
|
>
|
|
233
|
-
|
|
279
|
+
<img
|
|
280
|
+
v-if="appIcon"
|
|
281
|
+
:src="appIcon"
|
|
282
|
+
alt="App icon"
|
|
283
|
+
class="h-6 w-6 object-contain"
|
|
284
|
+
/>
|
|
285
|
+
<template v-else>
|
|
286
|
+
{{ collapsedTitle }}
|
|
287
|
+
</template>
|
|
234
288
|
</div>
|
|
235
289
|
</div>
|
|
236
290
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<MultilevelSidebar
|
|
6
6
|
:title="title"
|
|
7
|
+
:app-icon="appIcon"
|
|
7
8
|
:width="width"
|
|
8
9
|
:collapsed-width="collapsedWidth"
|
|
9
10
|
:main-menu="mainMenu"
|
|
@@ -50,6 +51,10 @@ export default {
|
|
|
50
51
|
type: String,
|
|
51
52
|
default: "",
|
|
52
53
|
},
|
|
54
|
+
appIcon: {
|
|
55
|
+
type: String,
|
|
56
|
+
default: "",
|
|
57
|
+
},
|
|
53
58
|
width: {
|
|
54
59
|
type: String,
|
|
55
60
|
default: "360px",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="overflow-hidden border rounded-lg shadow-sm component-card cp-card cp-border">
|
|
2
|
+
<div class="overflow-hidden border rounded-lg shadow-sm component-card cp-card cp-border text-[14px]">
|
|
3
3
|
<div class="flex items-center justify-between px-4 py-3 border-b cp-border cp-muted-50">
|
|
4
|
-
<h2 class="text-
|
|
4
|
+
<h2 class="text-[15px] font-semibold cp-text">{{ componentName }} Description</h2>
|
|
5
5
|
|
|
6
6
|
<div class="flex items-center gap-1">
|
|
7
7
|
<button
|
|
8
8
|
v-for="tab in tabs"
|
|
9
9
|
:key="tab.id"
|
|
10
10
|
@click="activeTab = tab.id"
|
|
11
|
-
:class="['px-3 py-1.5 text-
|
|
11
|
+
:class="['px-3 py-1.5 text-[13px] font-medium rounded-md transition-colors', activeTab === tab.id ? 'cp-tab-active' : 'cp-tab']">
|
|
12
12
|
{{ tab.label }}
|
|
13
13
|
</button>
|
|
14
14
|
</div>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<div class="p-4">
|
|
18
18
|
<div v-show="activeTab === 'props'">
|
|
19
19
|
<div v-if="props.length > 0" class="overflow-x-auto">
|
|
20
|
-
<table class="w-full text-
|
|
20
|
+
<table class="w-full text-[13px]">
|
|
21
21
|
<thead>
|
|
22
22
|
<tr class="border-b cp-border">
|
|
23
23
|
<th class="px-4 py-3 font-semibold text-left cp-text">Name</th>
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
<tbody>
|
|
31
31
|
<tr v-for="(prop, index) in props" :key="prop.name" :class="index % 2 === 0 ? 'cp-muted-30' : ''">
|
|
32
32
|
<td class="px-4 py-3">
|
|
33
|
-
<code class="text-
|
|
33
|
+
<code class="text-[13px] font-mono px-1.5 py-0.5 rounded cp-chip cp-chip-text">{{ prop.name }}</code>
|
|
34
34
|
</td>
|
|
35
|
-
<td class="px-4 py-3"><span class="font-mono text-
|
|
35
|
+
<td class="px-4 py-3"><span class="font-mono text-[13px] text-blue-600">{{ prop.type }}</span></td>
|
|
36
36
|
<td class="px-4 py-3">
|
|
37
|
-
<code v-if="prop.default !== undefined" class="font-mono text-
|
|
37
|
+
<code v-if="prop.default !== undefined" class="font-mono text-[13px] text-slate-700">{{ prop.default }}</code>
|
|
38
38
|
<span v-else class="cp-text-muted">-</span>
|
|
39
39
|
</td>
|
|
40
40
|
<td class="px-4 py-3 cp-text-muted">{{ prop.description }}</td>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
<div v-show="activeTab === 'slots'">
|
|
52
52
|
<div v-if="slots.length > 0" class="overflow-x-auto">
|
|
53
|
-
<table class="w-full text-
|
|
53
|
+
<table class="w-full text-[13px]">
|
|
54
54
|
<thead>
|
|
55
55
|
<tr class="border-b cp-border">
|
|
56
56
|
<th class="px-4 py-3 font-semibold text-left cp-text">Name</th>
|
|
@@ -62,10 +62,10 @@
|
|
|
62
62
|
<tbody>
|
|
63
63
|
<tr v-for="(slot, index) in slots" :key="slot.name" :class="index % 2 === 0 ? 'cp-muted-30' : ''">
|
|
64
64
|
<td class="px-4 py-3">
|
|
65
|
-
<code class="text-
|
|
65
|
+
<code class="text-[13px] font-mono px-1.5 py-0.5 rounded cp-chip cp-chip-text">{{ slot.name }}</code>
|
|
66
66
|
</td>
|
|
67
67
|
<td class="px-4 py-3">
|
|
68
|
-
<span :class="['inline-flex items-center px-2 py-0.5 rounded-full text-
|
|
68
|
+
<span :class="['inline-flex items-center px-2 py-0.5 rounded-full text-[13px] font-medium', slot.scoped ? 'bg-emerald-100 text-emerald-700' : 'cp-badge-muted']">
|
|
69
69
|
{{ slot.scoped ? "Yes" : "No" }}
|
|
70
70
|
</span>
|
|
71
71
|
</td>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="overflow-hidden border rounded-lg shadow-sm component-card cp-card cp-border">
|
|
2
|
+
<div class="overflow-hidden border rounded-lg shadow-sm component-card cp-card cp-border text-[14px]">
|
|
3
3
|
<div class="flex items-center justify-between px-4 py-3 border-b cp-border cp-muted-50">
|
|
4
|
-
<h2 class="text-
|
|
4
|
+
<h2 class="text-[15px] font-semibold cp-text">{{ componentName }} Preview</h2>
|
|
5
5
|
|
|
6
6
|
<div class="flex items-center gap-1">
|
|
7
7
|
<button
|
|
8
8
|
v-for="tab in tabs"
|
|
9
9
|
:key="tab.id"
|
|
10
10
|
@click="activeTab = tab.id"
|
|
11
|
-
:class="['px-3 py-1.5 text-
|
|
11
|
+
:class="['px-3 py-1.5 text-[13px] font-medium rounded-md transition-colors', activeTab === tab.id ? 'cp-tab-active' : 'cp-tab']">
|
|
12
12
|
{{ tab.label }}
|
|
13
13
|
</button>
|
|
14
14
|
</div>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
v-for="vp in previewViewports"
|
|
23
23
|
:key="vp.id"
|
|
24
24
|
@click="activeViewport = vp.id"
|
|
25
|
-
:class="['px-3 py-1.5 text-
|
|
25
|
+
:class="['px-3 py-1.5 text-[13px] font-semibold rounded-md transition-colors', activeViewport === vp.id ? 'cp-tab-active' : 'cp-tab']">
|
|
26
26
|
{{ vp.label }}
|
|
27
27
|
</button>
|
|
28
28
|
</div>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
<div v-show="activeTab === 'code'" class="relative">
|
|
39
39
|
<div class="absolute z-10 top-3 right-3">
|
|
40
|
-
<button @click="copyCode" class="flex items-center gap-1.5 px-3 py-1.5 text-
|
|
40
|
+
<button @click="copyCode" class="flex items-center gap-1.5 px-3 py-1.5 text-[13px] font-medium rounded-md transition-colors cp-chip cp-chip-hover cp-chip-text">
|
|
41
41
|
<svg
|
|
42
42
|
v-if="!copied"
|
|
43
43
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
</button>
|
|
73
73
|
</div>
|
|
74
74
|
|
|
75
|
-
<pre class="p-4 overflow-x-auto rounded-lg cp-pre">
|
|
76
|
-
<code class="font-mono text-
|
|
75
|
+
<pre class="p-4 overflow-x-auto rounded-lg text-[11px] leading-5 cp-pre">
|
|
76
|
+
<code class="font-mono text-[11px]" v-html="highlightedCode"></code>
|
|
77
77
|
</pre>
|
|
78
78
|
</div>
|
|
79
79
|
</div>
|
package/src/ui/kCode.vue
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<!-- kCode.vue -->
|
|
2
2
|
<template>
|
|
3
|
-
<div class="p-4 mt-3 overflow-hidden text-white whitespace-pre bg-gray-900 border rounded-lg border-primary/30">
|
|
3
|
+
<div class="p-4 mt-3 overflow-hidden text-[11px] leading-5 text-white whitespace-pre bg-gray-900 border rounded-lg border-primary/30">
|
|
4
4
|
<div class="overflow-auto">
|
|
5
|
-
<code>{{ normalizedContent }}</code>
|
|
5
|
+
<code class="font-mono text-[11px]">{{ normalizedContent }}</code>
|
|
6
6
|
</div>
|
|
7
7
|
</div>
|
|
8
8
|
</template>
|
|
@@ -5,7 +5,7 @@ export const K_BUTTON_BASE = "inline-flex flex-row items-center justify-center f
|
|
|
5
5
|
|
|
6
6
|
export const K_BUTTON_SIZE_STYLES = {
|
|
7
7
|
normal: {
|
|
8
|
-
regular: "h-
|
|
8
|
+
regular: "h-9 px-4 text-sm",
|
|
9
9
|
iconOnly: "h-10 w-10 p-0",
|
|
10
10
|
icon: "w-5 h-5",
|
|
11
11
|
loader: "w-5 h-5",
|
|
@@ -27,7 +27,7 @@ export const K_BUTTON_SIZE_STYLES = {
|
|
|
27
27
|
},
|
|
28
28
|
// Backward compatibility aliases
|
|
29
29
|
default: {
|
|
30
|
-
regular: "h-
|
|
30
|
+
regular: "h-9 px-4 text-sm",
|
|
31
31
|
iconOnly: "h-10 w-10 p-0",
|
|
32
32
|
icon: "w-5 h-5",
|
|
33
33
|
loader: "w-5 h-5",
|