ketekny-ui-kit 1.0.103 → 1.0.105
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/package.json +1 -1
- package/src/layout/kSingleColPage.vue +41 -2
- package/src/layout/kTwoColPage.vue +16 -2
- package/src/twoColLayout/components/MultilevelSidebar.vue +88 -29
- package/src/twoColLayout/components/SidebarMenuItem.vue +15 -12
- package/src/twoColLayout/components/TwoColLayout.vue +22 -7
package/package.json
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<main class="flex min-h-screen w-full max-w-none flex-col bg-slate-100">
|
|
3
|
-
<
|
|
3
|
+
<div
|
|
4
|
+
v-if="showHeaderExtraBeforeTitle"
|
|
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
|
+
:style="{ top: headerExtraTop }"
|
|
7
|
+
>
|
|
8
|
+
<div class="mx-auto flex w-full max-w-none items-center">
|
|
9
|
+
<slot name="header-extra" />
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<section
|
|
14
|
+
v-if="hasTopSection"
|
|
15
|
+
class="bg-white px-4 pb-4 pb-0 pt-8 sm:px-6 lg:px-8"
|
|
16
|
+
>
|
|
4
17
|
<div class="mx-auto flex w-full max-w-none flex-col gap-5">
|
|
5
18
|
<div
|
|
6
19
|
v-if="pageTitle || pageDescription"
|
|
@@ -31,7 +44,11 @@
|
|
|
31
44
|
</div>
|
|
32
45
|
</section>
|
|
33
46
|
|
|
34
|
-
<div
|
|
47
|
+
<div
|
|
48
|
+
v-if="showHeaderExtraAfterTitle"
|
|
49
|
+
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
|
+
:style="{ top: headerExtraTop }"
|
|
51
|
+
>
|
|
35
52
|
<div class="mx-auto flex w-full max-w-none items-center">
|
|
36
53
|
<slot name="header-extra" />
|
|
37
54
|
</div>
|
|
@@ -69,8 +86,30 @@ export default {
|
|
|
69
86
|
type: String,
|
|
70
87
|
default: '',
|
|
71
88
|
},
|
|
89
|
+
headerExtraTop: {
|
|
90
|
+
type: String,
|
|
91
|
+
default: '0px',
|
|
92
|
+
},
|
|
93
|
+
headerExtraBeforeTitle: {
|
|
94
|
+
type: Boolean,
|
|
95
|
+
default: false,
|
|
96
|
+
},
|
|
72
97
|
},
|
|
73
98
|
computed: {
|
|
99
|
+
hasTopSection() {
|
|
100
|
+
return Boolean(
|
|
101
|
+
this.pageTitle ||
|
|
102
|
+
this.pageDescription ||
|
|
103
|
+
this.externalUrl ||
|
|
104
|
+
this.$slots['header-actions']
|
|
105
|
+
)
|
|
106
|
+
},
|
|
107
|
+
showHeaderExtraBeforeTitle() {
|
|
108
|
+
return this.headerExtraBeforeTitle && Boolean(this.$slots['header-extra'])
|
|
109
|
+
},
|
|
110
|
+
showHeaderExtraAfterTitle() {
|
|
111
|
+
return !this.headerExtraBeforeTitle && Boolean(this.$slots['header-extra'])
|
|
112
|
+
},
|
|
74
113
|
externalUrlLabel() {
|
|
75
114
|
const target = String(this.externalUrl || '').trim()
|
|
76
115
|
if (!target) return ''
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<main class="flex h-screen w-full max-w-none flex-col overflow-hidden bg-slate-100">
|
|
3
|
-
<section
|
|
3
|
+
<section
|
|
4
|
+
v-if="hasTopSection"
|
|
5
|
+
class="shrink-0 bg-white px-4 pb-4 pb-0 pt-8 sm:px-6 lg:px-8"
|
|
6
|
+
>
|
|
4
7
|
<div class="mx-auto flex w-full max-w-none flex-col gap-5">
|
|
5
8
|
<div
|
|
6
9
|
v-if="pageTitle || pageDescription"
|
|
@@ -31,7 +34,10 @@
|
|
|
31
34
|
</div>
|
|
32
35
|
</section>
|
|
33
36
|
|
|
34
|
-
<div
|
|
37
|
+
<div
|
|
38
|
+
v-if="$slots['header-extra']"
|
|
39
|
+
class="shrink-0 border-b border-t border-slate-200 bg-slate-50 px-4 backdrop-blur"
|
|
40
|
+
>
|
|
35
41
|
<div class="mx-auto flex w-full max-w-none items-center">
|
|
36
42
|
<slot name="header-extra" />
|
|
37
43
|
</div>
|
|
@@ -80,6 +86,14 @@ export default {
|
|
|
80
86
|
},
|
|
81
87
|
},
|
|
82
88
|
computed: {
|
|
89
|
+
hasTopSection() {
|
|
90
|
+
return Boolean(
|
|
91
|
+
this.pageTitle ||
|
|
92
|
+
this.pageDescription ||
|
|
93
|
+
this.externalUrl ||
|
|
94
|
+
this.$slots['header-actions']
|
|
95
|
+
)
|
|
96
|
+
},
|
|
83
97
|
externalUrlLabel() {
|
|
84
98
|
const target = String(this.externalUrl || '').trim()
|
|
85
99
|
if (!target) return ''
|
|
@@ -17,6 +17,7 @@ import demoAvatarUrl from '../assets/placeholder-user.jpg'
|
|
|
17
17
|
|
|
18
18
|
const FAVORITES_STORAGE_KEY = 'ketekny-ui-sidebar-favorites'
|
|
19
19
|
const MENU_TAB_STORAGE_KEY = 'ketekny-ui-sidebar-menu-tab'
|
|
20
|
+
const LOGO_BASE_URL = 'https://s3.ketekny.gr/public/web-apps/logos'
|
|
20
21
|
|
|
21
22
|
export default {
|
|
22
23
|
name: 'MultilevelSidebar',
|
|
@@ -71,6 +72,11 @@ export default {
|
|
|
71
72
|
type: Boolean,
|
|
72
73
|
default: false,
|
|
73
74
|
},
|
|
75
|
+
theme: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: 'dark',
|
|
78
|
+
validator: value => ['dark', 'light'].includes(value),
|
|
79
|
+
},
|
|
74
80
|
},
|
|
75
81
|
emits: ['select', 'logo-click', 'signin', 'signup', 'signout', 'edit-profile', 'item-click'],
|
|
76
82
|
data() {
|
|
@@ -95,6 +101,17 @@ export default {
|
|
|
95
101
|
width: this.collapsed ? this.collapsedWidth : this.width,
|
|
96
102
|
}
|
|
97
103
|
},
|
|
104
|
+
themeClass() {
|
|
105
|
+
return this.theme === 'light' ? 'sidebar-theme-light' : 'sidebar-theme-dark'
|
|
106
|
+
},
|
|
107
|
+
activeExpandedLogoSrc() {
|
|
108
|
+
if (this.theme === 'light') return `${LOGO_BASE_URL}/logo-light.png`
|
|
109
|
+
return `${LOGO_BASE_URL}/logo-dark.png`
|
|
110
|
+
},
|
|
111
|
+
activeCollapsedLogoSrc() {
|
|
112
|
+
if (this.theme === 'light') return `${LOGO_BASE_URL}/logo_icon.jpg`
|
|
113
|
+
return `${LOGO_BASE_URL}/logo-icon-dark.png`
|
|
114
|
+
},
|
|
98
115
|
collapsedTitle() {
|
|
99
116
|
if (!this.title) return ''
|
|
100
117
|
const words = this.title.trim().split(/\s+/).filter(Boolean)
|
|
@@ -395,16 +412,17 @@ export default {
|
|
|
395
412
|
|
|
396
413
|
<template>
|
|
397
414
|
<aside
|
|
398
|
-
class="group/sidebar fixed inset-y-0 left-0 z-40 flex h-full shrink-0 flex-col border-r border-sidebar-border bg-sidebar text-sidebar-
|
|
415
|
+
class="group/sidebar fixed inset-y-0 left-0 z-40 flex h-full shrink-0 flex-col border-r border-[var(--sidebar-border)] bg-[var(--sidebar-bg)] text-[var(--sidebar-text)] transition-[width,transform] duration-200 ease-out lg:static lg:translate-x-0"
|
|
399
416
|
:style="sidebarWidthStyle"
|
|
400
417
|
:class="[
|
|
418
|
+
themeClass,
|
|
401
419
|
mobileOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0',
|
|
402
420
|
]"
|
|
403
421
|
>
|
|
404
422
|
<button
|
|
405
423
|
type="button"
|
|
406
424
|
v-tooltip.right="collapsed ? 'Ανάπτυξη πλαϊνού μενού' : 'Σύμπτυξη πλαϊνού μενού'"
|
|
407
|
-
class="absolute right-0 top-1/2 z-50 hidden h-14 w-6 -translate-y-1/2 translate-x-1/2 items-center justify-center rounded-r-md border border-sidebar-border bg-sidebar-
|
|
425
|
+
class="absolute right-0 top-1/2 z-50 hidden h-14 w-6 -translate-y-1/2 translate-x-1/2 items-center justify-center rounded-r-md border border-[var(--sidebar-border)] bg-[var(--sidebar-surface)] text-[var(--sidebar-text-muted)] opacity-85 shadow-lg shadow-[var(--sidebar-shadow)] transition-[color,opacity,background-color] hover:bg-[var(--sidebar-hover)] hover:opacity-100 hover:text-[var(--sidebar-text)] focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand lg:inline-flex"
|
|
408
426
|
:aria-label="collapsed ? 'Ανάπτυξη πλαϊνού μενού' : 'Σύμπτυξη πλαϊνού μενού'"
|
|
409
427
|
@click="toggleCollapsed"
|
|
410
428
|
>
|
|
@@ -415,14 +433,14 @@ export default {
|
|
|
415
433
|
<div class="relative flex items-center px-4 py-4" :class="collapsed ? 'justify-center' : 'gap-2.5'">
|
|
416
434
|
<img
|
|
417
435
|
v-if="collapsed"
|
|
418
|
-
src="
|
|
436
|
+
:src="activeCollapsedLogoSrc"
|
|
419
437
|
alt="Ketekny logo"
|
|
420
438
|
class="size-9 shrink-0 rounded-lg object-contain cursor-pointer"
|
|
421
439
|
@click="handleLogoClick"
|
|
422
440
|
/>
|
|
423
441
|
<img
|
|
424
442
|
v-else
|
|
425
|
-
src="
|
|
443
|
+
:src="activeExpandedLogoSrc"
|
|
426
444
|
alt="Ketekny logo"
|
|
427
445
|
class="min-w-0 flex-1 object-contain cursor-pointer"
|
|
428
446
|
@click="handleLogoClick"
|
|
@@ -430,7 +448,7 @@ export default {
|
|
|
430
448
|
</div>
|
|
431
449
|
|
|
432
450
|
<div v-if="title && !collapsed" class="px-4 pb-2">
|
|
433
|
-
<p class="text-xl font-bold text-center text-sidebar-
|
|
451
|
+
<p class="text-xl font-bold text-center text-[var(--sidebar-text)]">
|
|
434
452
|
{{ title }}
|
|
435
453
|
</p>
|
|
436
454
|
</div>
|
|
@@ -438,7 +456,7 @@ export default {
|
|
|
438
456
|
<div v-else-if="(title || appIcon) && collapsed" class="flex justify-center px-3 pb-2">
|
|
439
457
|
<div
|
|
440
458
|
v-tooltip.right="title"
|
|
441
|
-
class="flex h-10 w-10 items-center justify-center rounded-md border border-sidebar-border
|
|
459
|
+
class="flex h-10 w-10 items-center justify-center rounded-md border border-[var(--sidebar-border)] bg-[var(--sidebar-surface-muted)] text-[10px] font-bold tracking-[0.18em] text-[var(--sidebar-text-muted)]"
|
|
442
460
|
>
|
|
443
461
|
<img
|
|
444
462
|
v-if="appIcon"
|
|
@@ -452,19 +470,23 @@ export default {
|
|
|
452
470
|
</div>
|
|
453
471
|
</div>
|
|
454
472
|
|
|
473
|
+
<div v-if="$slots['sidebar-header']" :class="collapsed ? 'px-2 pb-2' : 'px-4 pb-3'">
|
|
474
|
+
<slot name="sidebar-header" />
|
|
475
|
+
</div>
|
|
476
|
+
|
|
455
477
|
<nav
|
|
456
478
|
class="flex-1 px-3 py-2"
|
|
457
479
|
:class="collapsed ? 'overflow-visible' : 'overflow-y-auto'"
|
|
458
480
|
aria-label="Main navigation"
|
|
459
481
|
>
|
|
460
482
|
<div v-if="showMenuTabs" class="mb-3 px-1">
|
|
461
|
-
<div class="inline-flex w-full rounded-lg bg-sidebar-
|
|
483
|
+
<div class="inline-flex w-full rounded-lg bg-[var(--sidebar-surface-muted)] p-1">
|
|
462
484
|
<button
|
|
463
485
|
type="button"
|
|
464
486
|
class="flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors"
|
|
465
487
|
:class="activeMenuTab === 'all'
|
|
466
|
-
? 'bg-sidebar text-sidebar-
|
|
467
|
-
: 'text-sidebar-muted hover:text-sidebar-
|
|
488
|
+
? 'bg-[var(--sidebar-surface)] text-[var(--sidebar-text)] shadow-sm'
|
|
489
|
+
: 'text-[var(--sidebar-text-muted)] hover:text-[var(--sidebar-text)]'"
|
|
468
490
|
@click="activeMenuTab = 'all'"
|
|
469
491
|
>
|
|
470
492
|
Όλα
|
|
@@ -473,8 +495,8 @@ export default {
|
|
|
473
495
|
type="button"
|
|
474
496
|
class="flex-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors"
|
|
475
497
|
:class="activeMenuTab === 'favorites'
|
|
476
|
-
? 'bg-sidebar text-sidebar-
|
|
477
|
-
: 'text-sidebar-muted hover:text-sidebar-
|
|
498
|
+
? 'bg-[var(--sidebar-surface)] text-[var(--sidebar-text)] shadow-sm'
|
|
499
|
+
: 'text-[var(--sidebar-text-muted)] hover:text-[var(--sidebar-text)]'"
|
|
478
500
|
@click="activeMenuTab = 'favorites'"
|
|
479
501
|
>
|
|
480
502
|
Αγαπημένα
|
|
@@ -485,7 +507,7 @@ export default {
|
|
|
485
507
|
<div v-if="!collapsed && (!showMenuTabs || activeMenuTab === 'all')" class="px-1 pb-3">
|
|
486
508
|
<div class="relative">
|
|
487
509
|
<Search
|
|
488
|
-
class="pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-sidebar-muted"
|
|
510
|
+
class="pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-[var(--sidebar-text-muted)]"
|
|
489
511
|
:stroke-width="2"
|
|
490
512
|
/>
|
|
491
513
|
<input
|
|
@@ -493,12 +515,12 @@ export default {
|
|
|
493
515
|
type="text"
|
|
494
516
|
placeholder="Αναζήτηση μενού..."
|
|
495
517
|
aria-label="Αναζήτηση μενού"
|
|
496
|
-
class="w-full
|
|
518
|
+
class="w-full rounded-md border border-[var(--sidebar-border)] bg-[var(--sidebar-surface)] py-2 pl-8 pr-9 text-[var(--sidebar-text)] placeholder:text-[var(--sidebar-text-muted)] focus:border-[var(--sidebar-border-strong)] focus:outline-none focus:ring-1 focus:ring-[var(--sidebar-border-strong)]"
|
|
497
519
|
/>
|
|
498
520
|
<button
|
|
499
521
|
v-if="query"
|
|
500
522
|
type="button"
|
|
501
|
-
class="absolute right-2 top-1/2 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md text-sidebar-muted transition-colors hover:bg-sidebar-
|
|
523
|
+
class="absolute right-2 top-1/2 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md text-[var(--sidebar-text-muted)] transition-colors hover:bg-[var(--sidebar-hover)] hover:text-[var(--sidebar-text)]"
|
|
502
524
|
aria-label="Καθαρισμός αναζήτησης"
|
|
503
525
|
@click="clearQuery"
|
|
504
526
|
>
|
|
@@ -517,6 +539,7 @@ export default {
|
|
|
517
539
|
:open-ids="effectiveOpenIds"
|
|
518
540
|
:collapsed="collapsed"
|
|
519
541
|
:favorites="favoriteIds"
|
|
542
|
+
:theme="theme"
|
|
520
543
|
@select="handleMenuSelect"
|
|
521
544
|
@toggle="toggle"
|
|
522
545
|
@toggle-favorite="toggleFavorite"
|
|
@@ -524,13 +547,13 @@ export default {
|
|
|
524
547
|
</ul>
|
|
525
548
|
<p
|
|
526
549
|
v-if="!collapsed && displayedMenuItems.length === 0"
|
|
527
|
-
class="px-3 py-6 text-center text-sidebar-muted"
|
|
550
|
+
class="px-3 py-6 text-center text-[var(--sidebar-text-muted)]"
|
|
528
551
|
>
|
|
529
552
|
Δεν βρέθηκαν αποτελέσματα.
|
|
530
553
|
</p>
|
|
531
554
|
</nav>
|
|
532
555
|
|
|
533
|
-
<div class="mt-auto border-t border-sidebar-border px-3 pb-3 pt-4">
|
|
556
|
+
<div class="mt-auto border-t border-[var(--sidebar-border)] px-3 pb-3 pt-4">
|
|
534
557
|
<div
|
|
535
558
|
:class="collapsed
|
|
536
559
|
? 'flex flex-col items-center gap-1'
|
|
@@ -548,8 +571,8 @@ export default {
|
|
|
548
571
|
activeId === link.id
|
|
549
572
|
? 'bg-brand text-brand-foreground font-medium'
|
|
550
573
|
: link.id === 'sign-out'
|
|
551
|
-
? 'text-
|
|
552
|
-
: 'text-sidebar-
|
|
574
|
+
? 'text-[var(--sidebar-danger)] hover:bg-[var(--sidebar-danger-bg)] hover:text-[var(--sidebar-danger-hover)]'
|
|
575
|
+
: 'text-[var(--sidebar-text-soft)] hover:bg-[var(--sidebar-hover)] hover:text-[var(--sidebar-text)]',
|
|
553
576
|
]"
|
|
554
577
|
:aria-label="link.label"
|
|
555
578
|
@click="handleFooterSelect(link.id)"
|
|
@@ -561,8 +584,8 @@ export default {
|
|
|
561
584
|
activeId === link.id
|
|
562
585
|
? 'text-brand-foreground'
|
|
563
586
|
: link.id === 'sign-out'
|
|
564
|
-
? 'text-
|
|
565
|
-
: 'text-sidebar-muted'
|
|
587
|
+
? 'text-[var(--sidebar-danger)]'
|
|
588
|
+
: 'text-[var(--sidebar-text-muted)]'
|
|
566
589
|
"
|
|
567
590
|
:stroke-width="2"
|
|
568
591
|
/>
|
|
@@ -575,7 +598,7 @@ export default {
|
|
|
575
598
|
aria-label="Account options"
|
|
576
599
|
>
|
|
577
600
|
<template #trigger>
|
|
578
|
-
<div class="flex w-full items-center gap-2 rounded-lg px-1 py-1 text-sidebar-
|
|
601
|
+
<div class="flex w-full items-center gap-2 rounded-lg px-1 py-1 text-[var(--sidebar-text-strong)] transition-colors duration-150">
|
|
579
602
|
<div class="sidebar-footer-item flex min-h-[44px] flex-1 items-center gap-2.5 rounded-lg bg-transparent px-1.5 py-1.5 text-left font-medium">
|
|
580
603
|
<img
|
|
581
604
|
:src="demoAvatarUrl"
|
|
@@ -584,12 +607,12 @@ export default {
|
|
|
584
607
|
/>
|
|
585
608
|
<span class="min-w-0 flex-1">
|
|
586
609
|
<span class="block truncate text-sm font-semibold">{{ accountDisplayName || 'Το προφίλ μου' }}</span>
|
|
587
|
-
<span class="block truncate text-xs font-normal text-sidebar-muted">{{ accountEmail }}</span>
|
|
610
|
+
<span class="block truncate text-xs font-normal text-[var(--sidebar-text-muted)]">{{ accountEmail }}</span>
|
|
588
611
|
</span>
|
|
589
612
|
</div>
|
|
590
613
|
|
|
591
614
|
<span
|
|
592
|
-
class="inline-flex size-9 items-center justify-center rounded-lg text-sidebar-muted"
|
|
615
|
+
class="inline-flex size-9 items-center justify-center rounded-lg text-[var(--sidebar-text-muted)]"
|
|
593
616
|
aria-hidden="true"
|
|
594
617
|
>
|
|
595
618
|
<Ellipsis class="size-4" :stroke-width="2" />
|
|
@@ -602,23 +625,23 @@ export default {
|
|
|
602
625
|
|
|
603
626
|
<div
|
|
604
627
|
v-if="!collapsed"
|
|
605
|
-
class="mt-3 border-t border-sidebar-border
|
|
628
|
+
class="mt-3 border-t border-[var(--sidebar-border)] px-2 pt-2 text-[11px] leading-snug text-[var(--sidebar-text-strong)]"
|
|
606
629
|
>
|
|
607
|
-
<div class="flex items-center gap-1.5 text-sidebar-
|
|
608
|
-
<Building2 class="size-3 shrink-0 text-sidebar-muted" :stroke-width="2" />
|
|
630
|
+
<div class="flex items-center gap-1.5 text-[var(--sidebar-text)]">
|
|
631
|
+
<Building2 class="size-3 shrink-0 text-[var(--sidebar-text-muted)]" :stroke-width="2" />
|
|
609
632
|
<p class="font-semibold uppercase tracking-[0.28em]">KETEKNY AE</p>
|
|
610
633
|
</div>
|
|
611
634
|
<div class="mt-1.5 pl-[18px]">
|
|
612
635
|
<p class="truncate ">Βερανζέρου 13, 10677, Αθήνα
|
|
613
636
|
<span> </span>
|
|
614
|
-
<a href="tel:+302103648337" class="transition-colors hover:text-sidebar-
|
|
637
|
+
<a href="tel:+302103648337" class="transition-colors hover:text-[var(--sidebar-text)]">
|
|
615
638
|
210 3648 337
|
|
616
639
|
</a></p>
|
|
617
640
|
|
|
618
641
|
<div class="flex flex-wrap items-center gap-x-3">
|
|
619
642
|
<a
|
|
620
643
|
:href="`mailto:${contactEmail}`"
|
|
621
|
-
class="transition-colors hover:text-sidebar-
|
|
644
|
+
class="transition-colors hover:text-[var(--sidebar-text)]"
|
|
622
645
|
>
|
|
623
646
|
{{ contactEmail }}
|
|
624
647
|
</a>
|
|
@@ -626,7 +649,7 @@ export default {
|
|
|
626
649
|
:href="helpUrl || 'https://help.ketekny.gr'"
|
|
627
650
|
target="_blank"
|
|
628
651
|
rel="noreferrer"
|
|
629
|
-
class="truncate transition-colors hover:text-sidebar-
|
|
652
|
+
class="truncate transition-colors hover:text-[var(--sidebar-text)]"
|
|
630
653
|
>
|
|
631
654
|
{{ helpUrl || 'https://help.ketekny.gr' }}
|
|
632
655
|
</a>
|
|
@@ -636,3 +659,39 @@ export default {
|
|
|
636
659
|
</div>
|
|
637
660
|
</aside>
|
|
638
661
|
</template>
|
|
662
|
+
|
|
663
|
+
<style scoped>
|
|
664
|
+
.sidebar-theme-dark {
|
|
665
|
+
--sidebar-bg: #0b0c0f;
|
|
666
|
+
--sidebar-surface: #161a22;
|
|
667
|
+
--sidebar-surface-muted: rgba(255, 255, 255, 0.06);
|
|
668
|
+
--sidebar-text: #eef2f7;
|
|
669
|
+
--sidebar-text-soft: rgba(238, 242, 247, 0.8);
|
|
670
|
+
--sidebar-text-strong: rgba(238, 242, 247, 0.9);
|
|
671
|
+
--sidebar-text-muted: #8a92a1;
|
|
672
|
+
--sidebar-border: rgba(255, 255, 255, 0.08);
|
|
673
|
+
--sidebar-border-strong: rgba(255, 255, 255, 0.16);
|
|
674
|
+
--sidebar-hover: rgba(255, 255, 255, 0.08);
|
|
675
|
+
--sidebar-shadow: rgba(0, 0, 0, 0.3);
|
|
676
|
+
--sidebar-danger: #f59e0b;
|
|
677
|
+
--sidebar-danger-hover: #fbbf24;
|
|
678
|
+
--sidebar-danger-bg: rgba(245, 158, 11, 0.12);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
.sidebar-theme-light {
|
|
682
|
+
--sidebar-bg: #f8fafc;
|
|
683
|
+
--sidebar-surface: #ffffff;
|
|
684
|
+
--sidebar-surface-muted: #eef4fb;
|
|
685
|
+
--sidebar-text: #0f172a;
|
|
686
|
+
--sidebar-text-soft: rgba(15, 23, 42, 0.8);
|
|
687
|
+
--sidebar-text-strong: rgba(15, 23, 42, 0.9);
|
|
688
|
+
--sidebar-text-muted: #64748b;
|
|
689
|
+
--sidebar-border: rgba(148, 163, 184, 0.28);
|
|
690
|
+
--sidebar-border-strong: rgba(100, 116, 139, 0.4);
|
|
691
|
+
--sidebar-hover: #e2e8f0;
|
|
692
|
+
--sidebar-shadow: rgba(15, 23, 42, 0.12);
|
|
693
|
+
--sidebar-danger: #ea580c;
|
|
694
|
+
--sidebar-danger-hover: #c2410c;
|
|
695
|
+
--sidebar-danger-bg: #ffedd5;
|
|
696
|
+
}
|
|
697
|
+
</style>
|
|
@@ -16,6 +16,7 @@ export default {
|
|
|
16
16
|
openIds: { type: Object, required: true },
|
|
17
17
|
collapsed: { type: Boolean, default: false },
|
|
18
18
|
favorites: { type: Object, default: null },
|
|
19
|
+
theme: { type: String, default: 'dark' },
|
|
19
20
|
},
|
|
20
21
|
emits: ['select', 'toggle', 'toggle-favorite'],
|
|
21
22
|
computed: {
|
|
@@ -100,8 +101,8 @@ export default {
|
|
|
100
101
|
isActiveLeaf || (isCollapsedTop && isActive)
|
|
101
102
|
? 'bg-brand text-brand-foreground font-medium'
|
|
102
103
|
: isActiveTrail
|
|
103
|
-
? 'text-sidebar-
|
|
104
|
-
: 'text-sidebar-
|
|
104
|
+
? 'text-[var(--sidebar-text)]'
|
|
105
|
+
: 'text-[var(--sidebar-text-soft)] hover:bg-[var(--sidebar-hover)] hover:text-[var(--sidebar-text)]',
|
|
105
106
|
]"
|
|
106
107
|
:aria-expanded="hasChildren && !isCollapsedTop ? isOpen : undefined"
|
|
107
108
|
:aria-label="isCollapsedTop ? item.label : undefined"
|
|
@@ -120,7 +121,7 @@ export default {
|
|
|
120
121
|
:class="[
|
|
121
122
|
isActiveLeaf || (isCollapsedTop && isActive)
|
|
122
123
|
? 'text-brand-foreground'
|
|
123
|
-
: 'text-sidebar-muted group-hover:text-sidebar-
|
|
124
|
+
: 'text-[var(--sidebar-text-muted)] group-hover:text-[var(--sidebar-text)]',
|
|
124
125
|
]"
|
|
125
126
|
:stroke-width="2"
|
|
126
127
|
/>
|
|
@@ -131,7 +132,7 @@ export default {
|
|
|
131
132
|
<span
|
|
132
133
|
v-if="item.badge != null"
|
|
133
134
|
class="ml-auto rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums"
|
|
134
|
-
:class="isActiveLeaf ? 'bg-brand-foreground/20 text-brand-foreground' : 'bg-sidebar-
|
|
135
|
+
:class="isActiveLeaf ? 'bg-brand-foreground/20 text-brand-foreground' : 'bg-[var(--sidebar-surface-muted)] text-[var(--sidebar-text-muted)]'"
|
|
135
136
|
>
|
|
136
137
|
{{ item.badge }}
|
|
137
138
|
</span>
|
|
@@ -139,14 +140,14 @@ export default {
|
|
|
139
140
|
<ExternalLink
|
|
140
141
|
v-if="isExternalLink"
|
|
141
142
|
class="size-3.5 shrink-0"
|
|
142
|
-
:class="isActiveLeaf ? 'text-brand-foreground' : 'text-sidebar-muted'"
|
|
143
|
+
:class="isActiveLeaf ? 'text-brand-foreground' : 'text-[var(--sidebar-text-muted)]'"
|
|
143
144
|
:stroke-width="2"
|
|
144
145
|
/>
|
|
145
146
|
|
|
146
147
|
<button
|
|
147
148
|
v-if="!hasChildren"
|
|
148
149
|
type="button"
|
|
149
|
-
class="inline-flex size-7 shrink-0 items-center justify-center rounded-md text-sidebar-muted opacity-0 transition-all duration-150 group-hover:opacity-100 hover:bg-sidebar-
|
|
150
|
+
class="inline-flex size-7 shrink-0 items-center justify-center rounded-md text-[var(--sidebar-text-muted)] opacity-0 transition-all duration-150 group-hover:opacity-100 hover:bg-[var(--sidebar-hover)] hover:text-[var(--sidebar-text)] focus-visible:opacity-100 focus-visible:outline-none"
|
|
150
151
|
:class="isFavorite ? 'opacity-100 text-amber-400 hover:text-amber-300' : ''"
|
|
151
152
|
:aria-label="isFavorite ? 'Remove from favorites' : 'Add to favorites'"
|
|
152
153
|
@click="toggleFavorite"
|
|
@@ -160,7 +161,7 @@ export default {
|
|
|
160
161
|
|
|
161
162
|
<ChevronRight
|
|
162
163
|
v-if="hasChildren"
|
|
163
|
-
class="size-4 shrink-0 text-sidebar-muted transition-transform duration-200"
|
|
164
|
+
class="size-4 shrink-0 text-[var(--sidebar-text-muted)] transition-transform duration-200"
|
|
164
165
|
:class="isOpen ? 'rotate-90' : ''"
|
|
165
166
|
:stroke-width="2"
|
|
166
167
|
/>
|
|
@@ -169,7 +170,7 @@ export default {
|
|
|
169
170
|
<span
|
|
170
171
|
v-if="isCollapsedTop && hasChildren"
|
|
171
172
|
class="absolute right-1.5 top-1.5 size-1.5 rounded-full"
|
|
172
|
-
:class="isActive ? 'bg-brand-foreground/80' : 'bg-sidebar-muted/60'"
|
|
173
|
+
:class="isActive ? 'bg-brand-foreground/80' : 'bg-[var(--sidebar-text-muted)]/60'"
|
|
173
174
|
aria-hidden="true"
|
|
174
175
|
/>
|
|
175
176
|
</button>
|
|
@@ -182,7 +183,7 @@ export default {
|
|
|
182
183
|
>
|
|
183
184
|
<ul
|
|
184
185
|
v-if="hasChildren && isOpen"
|
|
185
|
-
class="overflow-hidden border-l border-sidebar-border
|
|
186
|
+
class="overflow-hidden border-l border-[var(--sidebar-border)] ml-4 pl-2 transition-[height] duration-200 ease-out"
|
|
186
187
|
>
|
|
187
188
|
<SidebarMenuItem
|
|
188
189
|
v-for="child in item.children"
|
|
@@ -193,6 +194,7 @@ export default {
|
|
|
193
194
|
:open-ids="openIds"
|
|
194
195
|
:collapsed="collapsed"
|
|
195
196
|
:favorites="favorites"
|
|
197
|
+
:theme="theme"
|
|
196
198
|
@select="$emit('select', $event)"
|
|
197
199
|
@toggle="$emit('toggle', $event)"
|
|
198
200
|
@toggle-favorite="$emit('toggle-favorite', $event)"
|
|
@@ -205,14 +207,14 @@ export default {
|
|
|
205
207
|
class="invisible absolute left-full top-0 z-50 pl-2 opacity-0 transition-opacity duration-150 group-hover/fly:visible group-hover/fly:opacity-100"
|
|
206
208
|
>
|
|
207
209
|
<div
|
|
208
|
-
class="min-w-56 rounded-lg border border-sidebar-border bg-sidebar p-2 shadow-xl shadow-
|
|
210
|
+
class="min-w-56 rounded-lg border border-[var(--sidebar-border)] bg-[var(--sidebar-surface)] p-2 shadow-xl shadow-[var(--sidebar-shadow)]"
|
|
209
211
|
role="menu"
|
|
210
212
|
:aria-label="item.label"
|
|
211
213
|
>
|
|
212
214
|
<button
|
|
213
215
|
type="button"
|
|
214
216
|
class="mb-1 flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left font-semibold"
|
|
215
|
-
:class="isActive ? 'text-brand' : 'text-sidebar-
|
|
217
|
+
:class="isActive ? 'text-brand' : 'text-[var(--sidebar-text)] hover:bg-[var(--sidebar-hover)]'"
|
|
216
218
|
@click="!hasChildren && $emit('select', item)"
|
|
217
219
|
>
|
|
218
220
|
<component
|
|
@@ -224,7 +226,7 @@ export default {
|
|
|
224
226
|
<span class="truncate">{{ item.label }}</span>
|
|
225
227
|
<ExternalLink
|
|
226
228
|
v-if="isExternalLink"
|
|
227
|
-
class="ml-auto size-3.5 shrink-0 text-sidebar-muted"
|
|
229
|
+
class="ml-auto size-3.5 shrink-0 text-[var(--sidebar-text-muted)]"
|
|
228
230
|
:stroke-width="2"
|
|
229
231
|
/>
|
|
230
232
|
</button>
|
|
@@ -239,6 +241,7 @@ export default {
|
|
|
239
241
|
:open-ids="openIds"
|
|
240
242
|
:collapsed="false"
|
|
241
243
|
:favorites="favorites"
|
|
244
|
+
:theme="theme"
|
|
242
245
|
@select="$emit('select', $event)"
|
|
243
246
|
@toggle="$emit('toggle', $event)"
|
|
244
247
|
@toggle-favorite="$emit('toggle-favorite', $event)"
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<div v-if="mobileMenuOpen" class="fixed inset-0 z-30 bg-slate-950/50 backdrop-blur-[1px] lg:hidden" @click="closeMenu" />
|
|
4
4
|
|
|
5
5
|
<MultilevelSidebar
|
|
6
|
+
:theme="theme"
|
|
6
7
|
:title="title"
|
|
7
8
|
:app-icon="appIcon"
|
|
8
9
|
:width="width"
|
|
@@ -19,16 +20,29 @@
|
|
|
19
20
|
@edit-profile="handleEditProfile"
|
|
20
21
|
@item-click="handleItemClick"
|
|
21
22
|
@select="handleSelect"
|
|
22
|
-
|
|
23
|
+
>
|
|
24
|
+
<template v-if="$slots['sidebar-header']" #sidebar-header>
|
|
25
|
+
<slot name="sidebar-header" />
|
|
26
|
+
</template>
|
|
27
|
+
</MultilevelSidebar>
|
|
23
28
|
|
|
24
|
-
<main class="flex
|
|
29
|
+
<main class="flex min-h-0 flex-1 flex-col overflow-y-auto">
|
|
30
|
+
<div
|
|
31
|
+
v-if="$slots.header"
|
|
32
|
+
class="sticky top-0 z-20 shrink-0"
|
|
33
|
+
>
|
|
34
|
+
<slot name="header" />
|
|
35
|
+
</div>
|
|
25
36
|
<slot />
|
|
26
37
|
</main>
|
|
27
38
|
|
|
28
39
|
<button
|
|
29
|
-
v-if="
|
|
40
|
+
v-if="!mobileMenuOpen"
|
|
30
41
|
type="button"
|
|
31
|
-
class="fixed z-50 inline-flex items-center justify-center
|
|
42
|
+
class="fixed bottom-5 left-5 z-50 inline-flex size-14 items-center justify-center rounded-full transition-colors lg:hidden"
|
|
43
|
+
:class="theme === 'light'
|
|
44
|
+
? 'border border-slate-200 bg-white text-slate-700 shadow-lg shadow-slate-900/10 hover:bg-slate-100'
|
|
45
|
+
: 'bg-sidebar text-white shadow-lg shadow-black/25 hover:bg-sidebar-accent'"
|
|
32
46
|
aria-label="Open menu"
|
|
33
47
|
@click="toggleMenu">
|
|
34
48
|
<Menu class="size-6" :stroke-width="2.25" />
|
|
@@ -79,9 +93,10 @@ export default {
|
|
|
79
93
|
type: String,
|
|
80
94
|
default: "https://help.ketekny.gr",
|
|
81
95
|
},
|
|
82
|
-
|
|
83
|
-
type:
|
|
84
|
-
default:
|
|
96
|
+
theme: {
|
|
97
|
+
type: String,
|
|
98
|
+
default: "dark",
|
|
99
|
+
validator: value => ["dark", "light"].includes(value),
|
|
85
100
|
},
|
|
86
101
|
},
|
|
87
102
|
emits: ["select-menu", "logo-click", "signin", "signup", "signout", "edit-profile", "item-click"],
|