ketekny-ui-kit 1.0.129 → 1.0.130
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/index.js +4 -2
- package/package.json +1 -1
- package/src/layout/kFormSection.vue +55 -0
- package/src/layout/kSingleColPage.vue +31 -7
- package/src/layout/kTwoColPage.vue +20 -4
- package/src/ui/kCard.vue +51 -0
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import kMessage from './src/ui/kMessage.vue'
|
|
3
3
|
import kButton from './src/ui/kButton.vue'
|
|
4
4
|
import kCheckbox from './src/ui/kCheckbox.vue'
|
|
5
|
+
import kCard from './src/ui/kCard.vue'
|
|
5
6
|
import kChip from './src/ui/kChip.vue'
|
|
6
7
|
import kClipboard from './src/ui/kClipboard.vue'
|
|
7
8
|
import kCode from './src/ui/kCode.vue'
|
|
@@ -38,6 +39,7 @@ import kTree from './src/ui/kTree.vue'
|
|
|
38
39
|
import kAppHeader from './src/layout/kAppHeader.vue'
|
|
39
40
|
import kAppFooter from './src/layout/kAppFooter.vue'
|
|
40
41
|
import kAppMain from './src/layout/kAppMain.vue'
|
|
42
|
+
import kFormSection from './src/layout/kFormSection.vue'
|
|
41
43
|
import kHero from './src/layout/kHero.vue'
|
|
42
44
|
import kSingleColPage from './src/layout/kSingleColPage.vue'
|
|
43
45
|
import kMultiColPage from './src/layout/kMultiColPage.vue'
|
|
@@ -58,7 +60,7 @@ import tailwindPreset from './tailwind-preset.js'
|
|
|
58
60
|
// Named exports (tree-shaking friendly)
|
|
59
61
|
export {
|
|
60
62
|
// UI Components
|
|
61
|
-
kMessage, kCode, kToolbar, kTooltip, kTable, kTabs, kChip, kClipboard, kSpinner, kDatatable, kIcon, kMenu, kSkeleton, kProgressBar, kPagination, kTree,
|
|
63
|
+
kMessage, kCode, kToolbar, kTooltip, kTable, kTabs, kCard, kChip, kClipboard, kSpinner, kDatatable, kIcon, kMenu, kSkeleton, kProgressBar, kPagination, kTree,
|
|
62
64
|
|
|
63
65
|
// Form Components
|
|
64
66
|
kButton, kCheckbox, kSelect, kUploader, kToggle, kInput, kDateSelector, kEditor, kSelectButton, kTags, kSearch, kArrayList, kList, kTextArea, kForm, kOptionGroup,
|
|
@@ -67,7 +69,7 @@ export {
|
|
|
67
69
|
kDialog, kDrawer,
|
|
68
70
|
|
|
69
71
|
// Layout Components
|
|
70
|
-
kAppHeader, kAppFooter, kAppMain, kHero, kSingleColPage, kMultiColPage, kTwoColPage, twoColLayout, legacyTwoColLayout,
|
|
72
|
+
kAppHeader, kAppFooter, kAppMain, kFormSection, kHero, kSingleColPage, kMultiColPage, kTwoColPage, twoColLayout, legacyTwoColLayout,
|
|
71
73
|
|
|
72
74
|
// Plugins
|
|
73
75
|
toastPlugin, confirmPlugin, alertPlugin, tooltipPlugin, inputDialogPlugin,
|
package/package.json
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section :class="sectionClasses">
|
|
3
|
+
<div class="grid gap-6 lg:grid-cols-[240px_minmax(0,1fr)] lg:items-start">
|
|
4
|
+
<div>
|
|
5
|
+
<h3 class="text-lg font-semibold">
|
|
6
|
+
{{ title }}
|
|
7
|
+
</h3>
|
|
8
|
+
<p v-if="help" class="mt-1 text-sm text-slate-500">
|
|
9
|
+
{{ help }}
|
|
10
|
+
</p>
|
|
11
|
+
<div v-if="$slots.left" class="mt-4">
|
|
12
|
+
<slot name="left" />
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="w-full" :style="contentStyles">
|
|
17
|
+
<slot />
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</section>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
export default {
|
|
25
|
+
name: 'kFormSection',
|
|
26
|
+
props: {
|
|
27
|
+
title: {
|
|
28
|
+
type: String,
|
|
29
|
+
required: true,
|
|
30
|
+
},
|
|
31
|
+
help: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: '',
|
|
34
|
+
},
|
|
35
|
+
borderTop: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
default: false,
|
|
38
|
+
},
|
|
39
|
+
contentMaxWidth: {
|
|
40
|
+
type: String,
|
|
41
|
+
default: '56rem',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
computed: {
|
|
45
|
+
sectionClasses() {
|
|
46
|
+
return this.borderTop ? 'border-t border-slate-200 pt-8' : ''
|
|
47
|
+
},
|
|
48
|
+
contentStyles() {
|
|
49
|
+
return {
|
|
50
|
+
maxWidth: this.contentMaxWidth,
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
@@ -5,8 +5,16 @@
|
|
|
5
5
|
class="sticky z-30 border-b border-t border-slate-200 bg-slate-50 px-4 backdrop-blur sm:px-6 lg:px-8"
|
|
6
6
|
:style="{ top: resolvedHeaderExtraTop }"
|
|
7
7
|
>
|
|
8
|
-
<div class="mx-auto
|
|
9
|
-
<
|
|
8
|
+
<div class="mx-auto w-full max-w-none py-1">
|
|
9
|
+
<kToolbar
|
|
10
|
+
v-if="hasActions"
|
|
11
|
+
:actions="actions"
|
|
12
|
+
dense
|
|
13
|
+
variant="plain"
|
|
14
|
+
/>
|
|
15
|
+
<div v-if="$slots['header-extra']" class="flex items-center">
|
|
16
|
+
<slot name="header-extra" />
|
|
17
|
+
</div>
|
|
10
18
|
</div>
|
|
11
19
|
</div>
|
|
12
20
|
|
|
@@ -49,8 +57,16 @@
|
|
|
49
57
|
class="sticky z-30 border-b border-t border-slate-200 bg-slate-50 px-4 backdrop-blur sm:px-6 lg:px-8"
|
|
50
58
|
:style="{ top: resolvedHeaderExtraTop }"
|
|
51
59
|
>
|
|
52
|
-
<div class="mx-auto
|
|
53
|
-
<
|
|
60
|
+
<div class="mx-auto w-full max-w-none py-1">
|
|
61
|
+
<kToolbar
|
|
62
|
+
v-if="hasActions"
|
|
63
|
+
:actions="actions"
|
|
64
|
+
dense
|
|
65
|
+
variant="plain"
|
|
66
|
+
/>
|
|
67
|
+
<div v-if="$slots['header-extra']" class="flex items-center">
|
|
68
|
+
<slot name="header-extra" />
|
|
69
|
+
</div>
|
|
54
70
|
</div>
|
|
55
71
|
</div>
|
|
56
72
|
|
|
@@ -65,10 +81,11 @@
|
|
|
65
81
|
<script>
|
|
66
82
|
import packageJson from '../../package.json'
|
|
67
83
|
import kButton from '../ui/kButton.vue'
|
|
84
|
+
import kToolbar from '../ui/kToolbar.vue'
|
|
68
85
|
|
|
69
86
|
export default {
|
|
70
87
|
name: 'PageShell',
|
|
71
|
-
components: { kButton },
|
|
88
|
+
components: { kButton, kToolbar },
|
|
72
89
|
props: {
|
|
73
90
|
appTitle: {
|
|
74
91
|
type: String,
|
|
@@ -86,6 +103,10 @@ export default {
|
|
|
86
103
|
type: String,
|
|
87
104
|
default: '',
|
|
88
105
|
},
|
|
106
|
+
actions: {
|
|
107
|
+
type: Array,
|
|
108
|
+
default: () => [],
|
|
109
|
+
},
|
|
89
110
|
headerExtraTop: {
|
|
90
111
|
type: String,
|
|
91
112
|
default: '0px',
|
|
@@ -104,11 +125,14 @@ export default {
|
|
|
104
125
|
this.$slots['header-actions']
|
|
105
126
|
)
|
|
106
127
|
},
|
|
128
|
+
hasActions() {
|
|
129
|
+
return Array.isArray(this.actions) && this.actions.length > 0
|
|
130
|
+
},
|
|
107
131
|
showHeaderExtraBeforeTitle() {
|
|
108
|
-
return this.headerExtraBeforeTitle && Boolean(this.$slots['header-extra'])
|
|
132
|
+
return this.headerExtraBeforeTitle && (Boolean(this.$slots['header-extra']) || this.hasActions)
|
|
109
133
|
},
|
|
110
134
|
showHeaderExtraAfterTitle() {
|
|
111
|
-
return !this.headerExtraBeforeTitle && Boolean(this.$slots['header-extra'])
|
|
135
|
+
return !this.headerExtraBeforeTitle && (Boolean(this.$slots['header-extra']) || this.hasActions)
|
|
112
136
|
},
|
|
113
137
|
resolvedHeaderExtraTop() {
|
|
114
138
|
return this.hasTopSection ? this.headerExtraTop : '0px'
|
|
@@ -48,11 +48,19 @@
|
|
|
48
48
|
</section>
|
|
49
49
|
|
|
50
50
|
<div
|
|
51
|
-
v-if="$slots['header-extra']"
|
|
51
|
+
v-if="$slots['header-extra'] || hasActions"
|
|
52
52
|
class="shrink-0 border-b border-t border-slate-200 bg-slate-50 px-4 backdrop-blur"
|
|
53
53
|
>
|
|
54
|
-
<div class="mx-auto
|
|
55
|
-
<
|
|
54
|
+
<div class="mx-auto w-full max-w-none py-1">
|
|
55
|
+
<kToolbar
|
|
56
|
+
v-if="hasActions"
|
|
57
|
+
:actions="actions"
|
|
58
|
+
dense
|
|
59
|
+
variant="plain"
|
|
60
|
+
/>
|
|
61
|
+
<div v-if="$slots['header-extra']" class="flex items-center">
|
|
62
|
+
<slot name="header-extra" />
|
|
63
|
+
</div>
|
|
56
64
|
</div>
|
|
57
65
|
</div>
|
|
58
66
|
|
|
@@ -135,6 +143,7 @@
|
|
|
135
143
|
import packageJson from '../../package.json'
|
|
136
144
|
import kButton from '../ui/kButton.vue'
|
|
137
145
|
import kIcon from '../ui/kIcon.vue'
|
|
146
|
+
import kToolbar from '../ui/kToolbar.vue'
|
|
138
147
|
|
|
139
148
|
const LG_VIEWPORT_QUERY = '(min-width: 1024px)'
|
|
140
149
|
const MAIN_MENU_TOGGLE_EVENT = 'ketekny:two-col-layout-mobile-menu'
|
|
@@ -144,7 +153,7 @@ const MOBILE_SWIPE_VERTICAL_TOLERANCE = 48
|
|
|
144
153
|
|
|
145
154
|
export default {
|
|
146
155
|
name: 'MultiColPage',
|
|
147
|
-
components: { kButton, kIcon },
|
|
156
|
+
components: { kButton, kIcon, kToolbar },
|
|
148
157
|
props: {
|
|
149
158
|
appTitle: {
|
|
150
159
|
type: String,
|
|
@@ -162,6 +171,10 @@ export default {
|
|
|
162
171
|
type: String,
|
|
163
172
|
default: '',
|
|
164
173
|
},
|
|
174
|
+
actions: {
|
|
175
|
+
type: Array,
|
|
176
|
+
default: () => [],
|
|
177
|
+
},
|
|
165
178
|
sidebarWidth: {
|
|
166
179
|
type: String,
|
|
167
180
|
default: '300px',
|
|
@@ -234,6 +247,9 @@ export default {
|
|
|
234
247
|
hasRightSidebar() {
|
|
235
248
|
return Boolean(this.$slots['sidebar-right'])
|
|
236
249
|
},
|
|
250
|
+
hasActions() {
|
|
251
|
+
return Array.isArray(this.actions) && this.actions.length > 0
|
|
252
|
+
},
|
|
237
253
|
effectiveSidebarLeftWidth() {
|
|
238
254
|
return this.sidebarLeftWidth || this.sidebarWidth || '300px'
|
|
239
255
|
},
|
package/src/ui/kCard.vue
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<article class="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
|
|
3
|
+
<header
|
|
4
|
+
v-if="hasHeader"
|
|
5
|
+
class="border-b border-slate-200 px-5 py-4"
|
|
6
|
+
>
|
|
7
|
+
<slot name="header">
|
|
8
|
+
<div>
|
|
9
|
+
<p v-if="title" class="text-sm font-semibold text-slate-900">
|
|
10
|
+
{{ title }}
|
|
11
|
+
</p>
|
|
12
|
+
<p v-if="subtitle" :class="title ? 'mt-1 text-sm text-slate-500' : 'text-sm text-slate-500'">
|
|
13
|
+
{{ subtitle }}
|
|
14
|
+
</p>
|
|
15
|
+
</div>
|
|
16
|
+
</slot>
|
|
17
|
+
</header>
|
|
18
|
+
|
|
19
|
+
<div class="px-5 py-4">
|
|
20
|
+
<slot />
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<footer
|
|
24
|
+
v-if="$slots.footer"
|
|
25
|
+
class="border-t border-slate-200 px-5 py-4"
|
|
26
|
+
>
|
|
27
|
+
<slot name="footer" />
|
|
28
|
+
</footer>
|
|
29
|
+
</article>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script>
|
|
33
|
+
export default {
|
|
34
|
+
name: 'kCard',
|
|
35
|
+
props: {
|
|
36
|
+
title: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: '',
|
|
39
|
+
},
|
|
40
|
+
subtitle: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: '',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
computed: {
|
|
46
|
+
hasHeader() {
|
|
47
|
+
return Boolean(this.$slots.header || this.title || this.subtitle)
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
</script>
|