lkt-menu 1.0.0 → 1.0.2

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/dist/build.d.ts CHANGED
@@ -1,21 +1,41 @@
1
- declare function j(n: any, o: any, e: any): {
1
+ declare function se(n: any, t: any, l: any): {
2
2
  key: any;
3
3
  href: any;
4
- text: any;
4
+ label: any;
5
+ icon: string;
5
6
  isOpened: boolean;
7
+ isActive: boolean;
6
8
  children: any[];
7
- setChildren: (o: any) => h;
9
+ setChildren: (t: any) => K;
10
+ setOnClick: (t: any) => K;
11
+ onClick: any;
12
+ setIsActiveChecker: (t: any) => K;
13
+ isActiveChecker: any;
14
+ setIsActive: (t?: boolean) => K;
15
+ setLabel: (t: any) => K;
16
+ setIcon: (t: any) => K;
17
+ doClose: () => void;
8
18
  };
9
- declare namespace b {
19
+ declare namespace ne {
10
20
  function install(n: any): void;
11
21
  }
12
- declare class h {
13
- constructor(o: any, e: any, s: any);
22
+ declare class K {
23
+ constructor(t: any, l: any, c: any);
14
24
  key: any;
15
25
  href: any;
16
- text: any;
26
+ label: any;
27
+ icon: string;
17
28
  isOpened: boolean;
29
+ isActive: boolean;
18
30
  children: any[];
19
- setChildren(o: any): this;
31
+ setChildren(t: any): this;
32
+ setOnClick(t: any): this;
33
+ onClick: any;
34
+ setIsActiveChecker(t: any): this;
35
+ isActiveChecker: any;
36
+ setIsActive(t?: boolean): this;
37
+ setLabel(t: any): this;
38
+ setIcon(t: any): this;
39
+ doClose(): void;
20
40
  }
21
- export { j as createMenuEntry, b as default };
41
+ export { se as createMenuEntry, ne as default };
package/dist/build.js CHANGED
@@ -1,103 +1,163 @@
1
- import { defineComponent as p, ref as _, openBlock as t, createElementBlock as l, toDisplayString as U, createCommentVNode as d, createElementVNode as i, resolveComponent as V, createBlock as m, withCtx as $, createVNode as y, normalizeClass as E, Fragment as g, renderList as x, reactive as M } from "vue";
2
- class h {
3
- constructor(o, e, s) {
4
- this.key = "", this.href = "", this.text = "", this.isOpened = !1, this.children = [], this.key = o, this.href = e, this.text = s;
1
+ import { defineComponent as S, ref as L, useSlots as M, computed as a, watch as y, resolveComponent as E, openBlock as u, createElementBlock as o, normalizeClass as b, createElementVNode as m, createVNode as z, withCtx as A, unref as D, renderSlot as I, createCommentVNode as h, toDisplayString as F, Fragment as w, renderList as V, createBlock as U, createSlots as B, reactive as R } from "vue";
2
+ import { __ as T } from "lkt-i18n";
3
+ class K {
4
+ constructor(t, l, c) {
5
+ this.key = "", this.href = "", this.label = "", this.icon = "", this.onClick = void 0, this.isActiveChecker = void 0, this.isOpened = !1, this.isActive = !1, this.parent = void 0, this.children = [], this.key = t, this.href = l, this.label = c;
5
6
  }
6
- setChildren(o) {
7
- return this.children = o, this;
7
+ setChildren(t) {
8
+ return t.forEach((l) => l.parent = this), this.children = t, this;
9
+ }
10
+ setOnClick(t) {
11
+ return this.onClick = t, this;
12
+ }
13
+ setIsActiveChecker(t) {
14
+ return this.isActiveChecker = t, this;
15
+ }
16
+ setIsActive(t = !0) {
17
+ return this.isActive = t, this;
18
+ }
19
+ setLabel(t) {
20
+ return this.label = t, this;
21
+ }
22
+ setIcon(t) {
23
+ return this.icon = t, this;
24
+ }
25
+ doClose() {
26
+ this.isOpened = !1;
8
27
  }
9
28
  }
10
- const O = { class: "lkt-entry-content" }, w = /* @__PURE__ */ i("div", { class: "lkt-menu-entry-icon" }, " icn ", -1), B = {
29
+ const O = (n, t) => (t.forEach((l) => {
30
+ n.includes(l.key) || n.push(l.key), l.children.length > 0 && O(n, l.children);
31
+ }), n), q = { class: "lkt-menu-entry-main" }, G = { class: "lkt-entry-content" }, H = {
11
32
  key: 0,
12
- class: "lkt-menu-entry-text"
13
- }, f = /* @__PURE__ */ p({
14
- __name: "EntryContent",
15
- props: {
16
- modelValue: { default: () => new h("", "", "") }
17
- },
18
- setup(n) {
19
- const e = _(n.modelValue);
20
- return (s, v) => (t(), l("div", O, [
21
- w,
22
- e.value.text !== "" ? (t(), l("div", B, U(e.value.text), 1)) : d("", !0)
23
- ]));
24
- }
25
- }), L = { class: "lkt-menu-entry" }, N = { class: "lkt-menu-entry-main" }, z = {
33
+ class: "lkt-menu-entry-icon"
34
+ }, J = {
26
35
  key: 1,
27
- class: "lkt-anchor"
28
- }, D = {
36
+ class: "lkt-menu-entry-text"
37
+ }, P = {
29
38
  key: 0,
30
39
  class: "lkt-menu-entry-children"
31
- }, F = /* @__PURE__ */ p({
40
+ }, Q = /* @__PURE__ */ S({
32
41
  __name: "MenuItem",
33
42
  props: {
34
- modelValue: { default: () => new h("", "", "") }
43
+ modelValue: { default: () => new K("", "", "") }
35
44
  },
36
- setup(n) {
37
- const e = _(n.modelValue), s = () => {
45
+ emits: ["update:modelValue"],
46
+ setup(n, { emit: t }) {
47
+ const l = t, c = n, e = L(c.modelValue), r = M(), k = () => {
38
48
  e.value.isOpened = !e.value.isOpened;
39
- };
40
- return (v, u) => {
41
- const a = V("lkt-anchor"), c = V("menu-item", !0);
42
- return t(), l("div", L, [
43
- i("div", N, [
44
- e.value.href !== "" ? (t(), m(a, {
45
- key: 0,
46
- to: e.value.href
49
+ }, C = () => (e.value.children.length > 0 && k(), typeof e.value.onClick == "function" && e.value.onClick({
50
+ entry: e.value
51
+ }), 1), i = a(() => r["icon-" + e.value.key] || e.value.icon !== ""), d = a(() => {
52
+ let s = [];
53
+ return i.value && s.push("has-icon"), s.join(" ");
54
+ }), g = a(() => O([], e.value.children)), p = a(() => {
55
+ let s = [];
56
+ for (let f in r)
57
+ f.startsWith("icon-") && g.value.includes(f.substring(5)) && s.push(f);
58
+ return s;
59
+ }), v = a(() => e.value.label.startsWith("__:") ? T(e.value.label.substring(3)) : e.value.label), N = a(() => e.value.isActive ? !0 : typeof e.value.isActiveChecker == "function" ? !!e.value.isActiveChecker({
60
+ entry: e.value
61
+ }) : !1);
62
+ return y(() => c.modelValue, (s) => {
63
+ e.value = s;
64
+ }, { deep: !0 }), y(e, (s) => {
65
+ l("update:modelValue", s);
66
+ }, { deep: !0 }), (s, f) => {
67
+ const W = E("lkt-anchor"), x = E("menu-item", !0);
68
+ return u(), o("div", {
69
+ class: b(["lkt-menu-entry", d.value])
70
+ }, [
71
+ m("div", q, [
72
+ z(W, {
73
+ to: e.value.href,
74
+ "on-click": C,
75
+ "is-active": N.value
47
76
  }, {
48
- default: $(() => [
49
- y(f, {
50
- modelValue: e.value,
51
- "onUpdate:modelValue": u[0] || (u[0] = (r) => e.value = r)
52
- }, null, 8, ["modelValue"])
77
+ default: A(() => [
78
+ m("div", G, [
79
+ i.value ? (u(), o("div", H, [
80
+ D(r)["icon-" + e.value.key] ? I(s.$slots, "icon-" + e.value.key, {
81
+ key: e.value.key,
82
+ entry: e.value
83
+ }) : e.value.icon !== "" ? (u(), o("i", {
84
+ key: 1,
85
+ class: b(e.value.icon)
86
+ }, "icon", 2)) : h("", !0)
87
+ ])) : h("", !0),
88
+ e.value.label !== "" ? (u(), o("div", J, F(v.value), 1)) : h("", !0)
89
+ ])
53
90
  ]),
54
- _: 1
55
- }, 8, ["to"])) : (t(), l("div", z, [
56
- y(f, {
57
- modelValue: e.value,
58
- "onUpdate:modelValue": u[1] || (u[1] = (r) => e.value = r),
59
- onClick: s
60
- }, null, 8, ["modelValue"])
61
- ])),
62
- e.value.children.length > 0 ? (t(), l("div", {
63
- key: 2,
91
+ _: 3
92
+ }, 8, ["to", "is-active"]),
93
+ e.value.children.length > 0 ? (u(), o("div", {
94
+ key: 0,
64
95
  class: "lkt-menu-entry-toggle",
65
- onClick: s
96
+ onClick: k
66
97
  }, [
67
- i("div", {
68
- class: E(["lkt-menu-entry-toggle-triangle", e.value.isOpened ? "is-opened" : ""])
98
+ m("div", {
99
+ class: b(["lkt-menu-entry-toggle-triangle", e.value.isOpened ? "is-opened" : ""])
69
100
  }, null, 2)
70
- ])) : d("", !0)
101
+ ])) : h("", !0)
71
102
  ]),
72
- e.value.isOpened ? (t(), l("div", D, [
73
- (t(!0), l(g, null, x(e.value.children, (r, k) => (t(), m(c, {
74
- modelValue: e.value.children[k],
75
- "onUpdate:modelValue": (C) => e.value.children[k] = C
76
- }, null, 8, ["modelValue", "onUpdate:modelValue"]))), 256))
77
- ])) : d("", !0)
78
- ]);
103
+ e.value.isOpened ? (u(), o("div", P, [
104
+ (u(!0), o(w, null, V(e.value.children, (j, $) => (u(), U(x, {
105
+ modelValue: e.value.children[$],
106
+ "onUpdate:modelValue": (_) => e.value.children[$] = _,
107
+ key: j.key
108
+ }, B({ _: 2 }, [
109
+ V(p.value, (_) => ({
110
+ name: _,
111
+ fn: A(() => [
112
+ I(s.$slots, _)
113
+ ])
114
+ }))
115
+ ]), 1032, ["modelValue", "onUpdate:modelValue"]))), 128))
116
+ ])) : h("", !0)
117
+ ], 2);
79
118
  };
80
119
  }
81
- }), I = { class: "lkt-menu" }, S = /* @__PURE__ */ p({
120
+ }), X = { class: "lkt-menu-container" }, Y = { class: "lkt-menu" }, Z = /* @__PURE__ */ m("div", { class: "lkt-menu-outside" }, null, -1), ee = /* @__PURE__ */ S({
82
121
  __name: "LktMenu",
83
122
  props: {
84
123
  modelValue: { default: () => [] }
85
124
  },
86
- setup(n) {
87
- const e = _(n.modelValue);
88
- return (s, v) => (t(), l("div", I, [
89
- (t(!0), l(g, null, x(e.value, (u, a) => (t(), m(F, {
90
- modelValue: e.value[a],
91
- "onUpdate:modelValue": (c) => e.value[a] = c
92
- }, null, 8, ["modelValue", "onUpdate:modelValue"]))), 256))
125
+ emits: ["update:modelValue"],
126
+ setup(n, { emit: t }) {
127
+ const l = n, c = t, e = M(), r = L(l.modelValue), k = a(() => O([], r.value)), C = a(() => {
128
+ let i = [];
129
+ for (let d in e)
130
+ d.startsWith("icon-") && k.value.includes(d.substring(5)) && i.push(d);
131
+ return i;
132
+ });
133
+ return y(() => l.modelValue, (i) => {
134
+ r.value = i;
135
+ }, { deep: !0 }), y(r, (i) => {
136
+ c("update:modelValue", i);
137
+ }, { deep: !0 }), (i, d) => (u(), o("div", X, [
138
+ m("div", Y, [
139
+ (u(!0), o(w, null, V(r.value, (g, p) => (u(), U(Q, {
140
+ modelValue: r.value[p],
141
+ "onUpdate:modelValue": (v) => r.value[p] = v,
142
+ key: g.key
143
+ }, B({ _: 2 }, [
144
+ V(C.value, (v) => ({
145
+ name: v,
146
+ fn: A(() => [
147
+ I(i.$slots, v)
148
+ ])
149
+ }))
150
+ ]), 1032, ["modelValue", "onUpdate:modelValue"]))), 128))
151
+ ]),
152
+ Z
93
153
  ]));
94
154
  }
95
- }), b = {
155
+ }), ne = {
96
156
  install: (n) => {
97
- n.component("lkt-menu") === void 0 && n.component("lkt-menu", S);
157
+ n.component("lkt-menu") === void 0 && n.component("lkt-menu", ee);
98
158
  }
99
- }, j = (n, o, e) => M(new h(n, o, e));
159
+ }, se = (n, t, l) => R(new K(n, t, l));
100
160
  export {
101
- j as createMenuEntry,
102
- b as default
161
+ se as createMenuEntry,
162
+ ne as default
103
163
  };
@@ -1,9 +1,20 @@
1
1
  export declare class MenuEntry {
2
2
  key: string;
3
3
  href: string;
4
- text: string;
4
+ label: string;
5
+ icon: string;
6
+ onClick: Function | undefined;
7
+ isActiveChecker: Function | undefined;
5
8
  isOpened: boolean;
9
+ isActive: boolean;
10
+ parent: MenuEntry | undefined;
6
11
  children: MenuEntry[];
7
- constructor(key: string, href: string, text: string);
12
+ constructor(key: string, href: string, label: string);
8
13
  setChildren(children: MenuEntry[]): this;
14
+ setOnClick(fn: Function): this;
15
+ setIsActiveChecker(fn: Function): this;
16
+ setIsActive(enabled?: boolean): this;
17
+ setLabel(str: string): this;
18
+ setIcon(str: string): this;
19
+ doClose(): void;
9
20
  }
@@ -1,15 +1,40 @@
1
1
  import { MenuEntry } from "../classes/MenuEntry";
2
- declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
2
+ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
3
3
  modelValue?: MenuEntry | undefined;
4
4
  }>, {
5
5
  modelValue: () => MenuEntry;
6
- }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
6
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ "update:modelValue": (...args: any[]) => void;
8
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
7
9
  modelValue?: MenuEntry | undefined;
8
10
  }>, {
9
11
  modelValue: () => MenuEntry;
10
- }>>>, {
12
+ }>>> & {
13
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
14
+ }, {
11
15
  modelValue: MenuEntry;
12
- }, {}>;
16
+ }, {}>, Partial<Record<string, (_: {
17
+ key: string;
18
+ entry: {
19
+ key: string;
20
+ href: string;
21
+ label: string;
22
+ icon: string;
23
+ onClick: Function | undefined;
24
+ isActiveChecker: Function | undefined;
25
+ isOpened: boolean;
26
+ isActive: boolean;
27
+ parent: any | undefined;
28
+ children: any[];
29
+ setChildren: (children: MenuEntry[]) => MenuEntry;
30
+ setOnClick: (fn: Function) => MenuEntry;
31
+ setIsActiveChecker: (fn: Function) => MenuEntry;
32
+ setIsActive: (enabled?: boolean) => MenuEntry;
33
+ setLabel: (str: string) => MenuEntry;
34
+ setIcon: (str: string) => MenuEntry;
35
+ doClose: () => void;
36
+ };
37
+ }) => any>> & Partial<Record<any, (_: {}) => any>>>;
13
38
  export default _default;
14
39
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
15
40
  type __VLS_TypePropsToRuntimeProps<T> = {
@@ -28,3 +53,8 @@ type __VLS_WithDefaults<P, D> = {
28
53
  type __VLS_Prettify<T> = {
29
54
  [K in keyof T]: T[K];
30
55
  } & {};
56
+ type __VLS_WithTemplateSlots<T, S> = T & {
57
+ new (): {
58
+ $slots: S;
59
+ };
60
+ };
@@ -0,0 +1,2 @@
1
+ import { MenuEntry } from "../classes/MenuEntry";
2
+ export declare const fetchKeys: (r: string[], entries: MenuEntry[]) => string[];
@@ -1,15 +1,19 @@
1
1
  import { MenuEntry } from "../classes/MenuEntry";
2
- declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
2
+ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
3
3
  modelValue?: MenuEntry[] | undefined;
4
4
  }>, {
5
5
  modelValue: () => never[];
6
- }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
6
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ "update:modelValue": (...args: any[]) => void;
8
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
7
9
  modelValue?: MenuEntry[] | undefined;
8
10
  }>, {
9
11
  modelValue: () => never[];
10
- }>>>, {
12
+ }>>> & {
13
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
14
+ }, {
11
15
  modelValue: MenuEntry[];
12
- }, {}>;
16
+ }, {}>, Partial<Record<any, (_: {}) => any>>>;
13
17
  export default _default;
14
18
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
15
19
  type __VLS_TypePropsToRuntimeProps<T> = {
@@ -28,3 +32,8 @@ type __VLS_WithDefaults<P, D> = {
28
32
  type __VLS_Prettify<T> = {
29
33
  [K in keyof T]: T[K];
30
34
  } & {};
35
+ type __VLS_WithTemplateSlots<T, S> = T & {
36
+ new (): {
37
+ $slots: S;
38
+ };
39
+ };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .lkt-menu-entry-toggle-triangle{width:0px;height:0px;border-style:solid;border-width:10px 10px 0 10px;border-color:#FF4532 transparent transparent transparent;transform:rotate(0);transition:all linear .2s}.lkt-menu-entry-toggle-triangle.is-opened{transform:rotate(180deg)}.lkt-entry-content{display:inline-flex;flex-direction:row;gap:10px}.lkt-menu-entry-toggle{display:inline-flex;flex-direction:row;align-items:center;justify-content:center}
1
+ .lkt-menu{background:var(--lkt-menu-bg);padding:var(--lkt-menu-padding);max-width:var(--lkt-menu-max-width);width:var(--lkt-menu-width);height:100%}.lkt-menu-entry-toggle-triangle{width:0;height:0;border-style:solid;border-width:10px 10px 0 10px;border-color:var(--lkt-menu-color-toggle) transparent transparent transparent;transform:rotate(0);transition:all linear .2s}.lkt-menu-entry-toggle-triangle.is-opened{transform:rotate(180deg)}.lkt-entry-content{display:inline-flex;flex-direction:row;gap:var(--lkt-menu-gap)}.lkt-menu-entry-toggle{display:inline-flex;flex-direction:row;align-items:center;justify-content:center}.lkt-menu-entry{padding:var(--lkt-menu-padding-entry)}.lkt-menu-entry .lkt-anchor{width:100%}.lkt-menu-entry-main{display:flex;justify-content:space-between}.lkt-entry-content{font-size:var(--lkt-menu-font-size);width:100%}.lkt-menu-outside{position:fixed;top:64px;right:0;left:0;bottom:0;background:var(--lkt-menu-bg-outside);z-index:-1}.lkt-menu-entry-children{padding:var(--lkt-menu-padding-children)}.lkt-menu-entry-text{padding:var(--lkt-menu-padding-text-without-icon)}.lkt-menu.has-icon .lkt-menu-entry-text{padding:var(--lkt-menu-padding-text)}.lkt-menu.has-icon .lkt-menu-entry-icon+.lkt-menu-entry-text{padding:var(--lkt-menu-padding-text-with-icon)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lkt-menu",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "lkt",
@@ -53,6 +53,7 @@
53
53
  "lkt-control-tools": "^1.0.3",
54
54
  "lkt-events": "^1.0.2",
55
55
  "lkt-http-client": "^1.0.21",
56
+ "lkt-i18n": "^1.0.4",
56
57
  "lkt-loader": "^1.0.1",
57
58
  "lkt-modal-confirm": "^1.0.0",
58
59
  "lkt-string-tools": "^1.0.1",
@@ -1,7 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import {MenuEntry} from "../classes/MenuEntry";
3
- import {ref} from "vue";
4
- import EntryContent from "./EntryContent.vue";
3
+ import {computed, ref, useSlots, watch} from "vue";
4
+ import {LktObject} from "lkt-ts-interfaces";
5
+ import {fetchKeys} from "../functions/helpers";
6
+ import {__} from "lkt-i18n";
7
+
8
+ const emit = defineEmits(['update:modelValue']);
5
9
 
6
10
  const props = withDefaults(defineProps<{
7
11
  modelValue?: MenuEntry
@@ -11,28 +15,110 @@ const props = withDefaults(defineProps<{
11
15
 
12
16
  const entry = ref(props.modelValue);
13
17
 
18
+ const slots = useSlots();
19
+
14
20
  const onClickToggle = () => {
15
- entry.value.isOpened = !entry.value.isOpened;
16
- }
21
+ entry.value.isOpened = !entry.value.isOpened;
22
+ },
23
+ onClick = () => {
24
+ if (entry.value.children.length > 0) onClickToggle();
25
+ if (typeof entry.value.onClick === 'function') {
26
+ entry.value.onClick({
27
+ entry: entry.value
28
+ });
29
+ }
30
+ return 1;
31
+ };
32
+
33
+ const canRenderIcon = computed(() => {
34
+ return slots['icon-' + entry.value.key]
35
+ || entry.value.icon !== '';
36
+ }),
37
+ classes = computed(() => {
38
+ let r = [];
39
+ if (canRenderIcon.value) r.push('has-icon');
40
+ return r.join(' ');
41
+ });
42
+
43
+ const availableKeys = computed(() => {
44
+ let r: string[] = [];
45
+ return fetchKeys(r, entry.value.children);
46
+ }),
47
+ entryIconSlots = computed((): LktObject => {
48
+ let r = [];
49
+ for (let k in slots) {
50
+ if (k.startsWith('icon-')) {
51
+ if (availableKeys.value.includes(k.substring(5))) {
52
+ r.push(k);
53
+ }
54
+ }
55
+ }
56
+ return r;
57
+ }),
58
+ computedLabel = computed(() => {
59
+ if (entry.value.label.startsWith('__:')) {
60
+ return __(entry.value.label.substring(3));
61
+ }
62
+ return entry.value.label;
63
+ }),
64
+ computedIsActive = computed(() => {
65
+ if (entry.value.isActive) return true;
66
+
67
+ if (typeof entry.value.isActiveChecker === 'function') {
68
+ let r = entry.value.isActiveChecker({
69
+ entry: entry.value
70
+ });
71
+ return !!r;
72
+ }
73
+
74
+ return false;
75
+ });
76
+
77
+ watch(() => props.modelValue, (v) => {
78
+ entry.value = v
79
+ }, {deep: true});
80
+ watch(entry, (v) => {
81
+ emit('update:modelValue', v)
82
+ }, {deep: true})
17
83
  </script>
18
84
 
19
85
  <template>
20
- <div class="lkt-menu-entry">
21
- <div class="lkt-menu-entry-main">
22
- <lkt-anchor v-if="entry.href !== ''" :to="entry.href">
23
- <entry-content v-model="entry"/>
24
- </lkt-anchor>
25
- <div class="lkt-anchor" v-else>
26
- <entry-content v-model="entry" @click="onClickToggle"/>
86
+ <div class="lkt-menu-entry" :class="classes">
87
+ <div class="lkt-menu-entry-main">
88
+ <lkt-anchor
89
+ :to="entry.href"
90
+ :on-click="onClick"
91
+ :is-active="computedIsActive"
92
+ >
93
+ <div class="lkt-entry-content">
94
+ <div class="lkt-menu-entry-icon" v-if="canRenderIcon">
95
+ <template v-if="slots['icon-'+entry.key]">
96
+ <slot :name="'icon-'+entry.key"
97
+ :key="entry.key"
98
+ :entry="entry"/>
99
+ </template>
100
+ <template v-else-if="entry.icon !== ''">
101
+ <i :class="entry.icon">icon</i>
102
+ </template>
103
+ </div>
104
+ <div class="lkt-menu-entry-text" v-if="entry.label !== ''">
105
+ {{ computedLabel }}
106
+ </div>
107
+ </div>
108
+ </lkt-anchor>
109
+
110
+ <div class="lkt-menu-entry-toggle" v-if="entry.children.length > 0" @click="onClickToggle">
111
+ <div class="lkt-menu-entry-toggle-triangle" :class="entry.isOpened ? 'is-opened' : '' "/>
112
+ </div>
27
113
  </div>
28
- <div class="lkt-menu-entry-toggle" v-if="entry.children.length > 0" @click="onClickToggle">
29
- <div class="lkt-menu-entry-toggle-triangle" :class="entry.isOpened ? 'is-opened' : '' "/>
114
+ <div class="lkt-menu-entry-children" v-if="entry.isOpened">
115
+ <menu-item v-for="(child, i) in entry.children" v-model="entry.children[i]" :key="child.key">
116
+ <template v-for="slot in entryIconSlots" v-slot:[slot]>
117
+ <slot :name="slot"/>
118
+ </template>
119
+ </menu-item>
30
120
  </div>
31
121
  </div>
32
- <div class="lkt-menu-entry-children" v-if="entry.isOpened">
33
- <menu-item v-for="(_, i) in entry.children" v-model="entry.children[i]"/>
34
- </div>
35
- </div>
36
122
  </template>
37
123
 
38
124
  <style scoped>
@@ -1,7 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import {MenuEntry} from "../classes/MenuEntry";
3
3
  import MenuItem from "../components/MenuItem.vue";
4
- import {ref} from "vue";
4
+ import {computed, ref, useSlots, watch} from "vue";
5
+ import {LktObject} from "lkt-ts-interfaces";
6
+ import {fetchKeys} from "../functions/helpers";
5
7
 
6
8
  const props = withDefaults(defineProps<{
7
9
  modelValue?: MenuEntry[]
@@ -9,13 +11,48 @@ const props = withDefaults(defineProps<{
9
11
  modelValue: () => []
10
12
  });
11
13
 
14
+ const emit = defineEmits(['update:modelValue']);
15
+
16
+ const slots = useSlots();
17
+
12
18
  const entries = ref(props.modelValue);
19
+
20
+ const availableKeys = computed(() => {
21
+ let r:string[] = [];
22
+ return fetchKeys(r, entries.value);
23
+ }),
24
+ entryIconSlots = computed((): LktObject => {
25
+ let r = [];
26
+ for (let k in slots) {
27
+ if (k.startsWith('icon-')) {
28
+ if (availableKeys.value.includes(k.substring(5))) {
29
+ r.push(k);
30
+ }
31
+ }
32
+ }
33
+ return r;
34
+ });
35
+
36
+ watch(() => props.modelValue, (v) => {
37
+ entries.value = v;
38
+ }, {deep: true})
39
+
40
+ watch(entries, (v) => {
41
+ emit('update:modelValue', v);
42
+ }, {deep: true})
13
43
  </script>
14
44
 
15
45
  <template>
16
- <div class="lkt-menu">
17
- <menu-item v-for="(_, i) in entries" v-model="entries[i]"/>
18
- </div>
46
+ <div class="lkt-menu-container">
47
+ <div class="lkt-menu">
48
+ <menu-item v-for="(entry, i) in entries" v-model="entries[i]" :key="entry.key">
49
+ <template v-for="slot in entryIconSlots" v-slot:[slot]>
50
+ <slot :name="slot"/>
51
+ </template>
52
+ </menu-item>
53
+ </div>
54
+ <div class="lkt-menu-outside"/>
55
+ </div>
19
56
  </template>
20
57
 
21
58
  <style scoped>
package/theme/default.css CHANGED
@@ -1,7 +1,7 @@
1
1
  :root {
2
2
  /** Font */
3
3
  --lkt-menu-font-family: system-ui, Helvetica;
4
- --lkt-menu-font-size: 17px;
4
+ --lkt-menu-font-size: 16px;
5
5
  --lkt-menu-font-weight: 400;
6
6
  --lkt-menu-line-height: 1;
7
7
  --lkt-menu-text-align: left;
@@ -10,45 +10,25 @@
10
10
 
11
11
  /** Sizing */
12
12
  --lkt-menu-width: 100%;
13
- --lkt-menu-min-width: 150px;
14
- --lkt-menu-min-height: 35px;
15
- --lkt-menu-padding: 7px;
16
- --lkt-menu-gap: 5px;
17
-
18
- /** Border */
19
- --lkt-menu-border-radius: 5px;
20
- --lkt-menu-border-width: 1px;
21
- --lkt-menu-border-width-hover: 1px;
22
- --lkt-menu-border-style: solid;
13
+ --lkt-menu-min-width: 0;
14
+ --lkt-menu-max-width: initial;
15
+ --lkt-menu-min-height: 0;
16
+ --lkt-menu-padding: 15px;
17
+ --lkt-menu-gap: 15px;
23
18
 
24
19
  /** Colors */
25
- --lkt-menu-color: #ffffff;
26
- --lkt-menu-bg: #007ebc;
27
- --lkt-menu-border-color: #ddd;
28
-
29
- /** Effects */
30
- --lkt-menu-shadow: none;
31
- --lkt-menu-transition: all linear 100ms;
32
-
33
- /** State: hover */
34
- --lkt-menu-color-hover: #ffffff;
35
- --lkt-menu-bg-hover: #007ebc;
36
- --lkt-menu-border-color-hover: #ddd;
37
-
38
- /** State: Focus */
39
- --lkt-menu-border-color-focus: var(--focus-color);
40
- --lkt-menu-shadow-focus: 0 0 0 2px var(--focus-color);
20
+ --lkt-menu-bg: #ffffff;
21
+ --lkt-menu-color-toggle: #444444;
41
22
 
42
- /** State: Disabled */
43
- --lkt-menu-color-disabled: var(--disabled-contrast);
44
- --lkt-menu-bg-disabled: var(--disabled-color);
45
- --lkt-menu-border-color-disabled: var(--disabled-color);
23
+ /** Sizing: Entries */
24
+ --lkt-menu-padding-entry: 15px;
25
+ --lkt-menu-padding-text: 0 0 0 30px;
26
+ --lkt-menu-padding-text-with-icon: 0;
27
+ --lkt-menu-padding-text-without-icon: 0;
46
28
 
47
- /** Internal image */
48
- --lkt-button-img-max-width: 50px;
49
- --lkt-button-img-max-height: 50px;
29
+ /** Sizing: Children */
30
+ --lkt-menu-padding-children: 0 0 0 10px;
50
31
 
51
- /** Split Button */
52
- --lkt-button-split-arrow-width: 40px;
53
- --lkt-button-split-arrow-bg: transparent;
32
+ /** Colors: Outside */
33
+ --lkt-menu-bg-outside: rgba(255, 255, 255, 0.75);
54
34
  }
@@ -1,30 +0,0 @@
1
- import { MenuEntry } from "../classes/MenuEntry";
2
- declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
3
- modelValue?: MenuEntry | undefined;
4
- }>, {
5
- modelValue: () => MenuEntry;
6
- }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
7
- modelValue?: MenuEntry | undefined;
8
- }>, {
9
- modelValue: () => MenuEntry;
10
- }>>>, {
11
- modelValue: MenuEntry;
12
- }, {}>;
13
- export default _default;
14
- type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
15
- type __VLS_TypePropsToRuntimeProps<T> = {
16
- [K in keyof T]-?: {} extends Pick<T, K> ? {
17
- type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
18
- } : {
19
- type: import('vue').PropType<T[K]>;
20
- required: true;
21
- };
22
- };
23
- type __VLS_WithDefaults<P, D> = {
24
- [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
25
- default: D[K];
26
- }> : P[K];
27
- };
28
- type __VLS_Prettify<T> = {
29
- [K in keyof T]: T[K];
30
- } & {};
@@ -1,27 +0,0 @@
1
- <script setup lang="ts">
2
- import {MenuEntry} from "../classes/MenuEntry";
3
- import {ref} from "vue";
4
-
5
- const props = withDefaults(defineProps<{
6
- modelValue?: MenuEntry
7
- }>(), {
8
- modelValue: () => (new MenuEntry('', '', ''))
9
- });
10
-
11
- const entry = ref(props.modelValue);
12
- </script>
13
-
14
- <template>
15
- <div class="lkt-entry-content">
16
- <div class="lkt-menu-entry-icon">
17
- icn
18
- </div>
19
- <div class="lkt-menu-entry-text" v-if="entry.text !== ''">
20
- {{entry.text}}
21
- </div>
22
- </div>
23
- </template>
24
-
25
- <style scoped>
26
-
27
- </style>