feat: improve sidebar handling
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
16ca4efc03
commit
aba8737c38
6 changed files with 93 additions and 15 deletions
|
|
@ -117,16 +117,27 @@
|
|||
width: 4rem; /* Collapsed: w-16 */
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Header - Logo Centering
|
||||
============================================ */
|
||||
|
||||
/* Header container with smooth transition for gap */
|
||||
.sidebar > div:first-child {
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Text Labels - Hide in Collapsed State
|
||||
============================================ */
|
||||
|
||||
.menu-label {
|
||||
@apply transition-all duration-200 whitespace-nowrap;
|
||||
transition-delay: 0ms; /* Expanded: sofort sichtbar */
|
||||
}
|
||||
|
||||
[data-sidebar-expanded="false"] .sidebar .menu-label {
|
||||
@apply opacity-0 w-0 overflow-hidden pointer-events-none;
|
||||
transition-delay: 300ms; /* Warte bis Sidebar eingeklappt ist (300ms = duration der Sidebar width transition) */
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
|
|
@ -165,6 +176,11 @@
|
|||
@apply block;
|
||||
}
|
||||
|
||||
/* Collapsed menu group button: center icon under logo */
|
||||
.sidebar .collapsed-menu-group button {
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Elements Only Visible in Expanded State
|
||||
============================================ */
|
||||
|
|
@ -192,20 +208,79 @@
|
|||
}
|
||||
|
||||
/* ============================================
|
||||
Menu Item Alignment - Center in Collapsed State
|
||||
Menu Item Alignment - Icons Centered Under Logo
|
||||
============================================ */
|
||||
|
||||
/* Base alignment: Icons centered under logo (32px from left edge)
|
||||
- Logo center: 16px padding + 16px (half of 32px) = 32px
|
||||
- Icon center should be at 32px: 22px start + 10px (half of 20px) = 32px
|
||||
- Menu has p-2 (8px), so links need 14px additional padding-left */
|
||||
|
||||
.sidebar .menu > li > a,
|
||||
.sidebar .menu > li > button {
|
||||
@apply transition-all duration-300;
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
/* Collapsed state: same padding to keep icons at same position
|
||||
- Remove gap so label (which is opacity-0 w-0) doesn't create space
|
||||
- Keep padding-left at 14px so icons stay centered under logo */
|
||||
[data-sidebar-expanded="false"] .sidebar .menu > li > a,
|
||||
[data-sidebar-expanded="false"] .sidebar .menu > li > button {
|
||||
@apply justify-center px-0;
|
||||
@apply gap-0;
|
||||
padding-left: 14px;
|
||||
padding-right: 14px; /* Center icon horizontally in 64px sidebar */
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Footer Button Alignment - Center in Collapsed State
|
||||
Footer Button Alignment - Left Aligned in Collapsed State
|
||||
============================================ */
|
||||
|
||||
[data-sidebar-expanded="false"] .sidebar .dropdown > button {
|
||||
@apply justify-center px-0;
|
||||
@apply px-0;
|
||||
/* Buttons stay at left position, only label disappears */
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
User Menu Button - Focus Ring on Avatar
|
||||
============================================ */
|
||||
|
||||
/* Focus ring appears on the avatar when button is focused */
|
||||
.user-menu-button:focus .avatar > div {
|
||||
@apply ring-2 ring-primary ring-offset-2 ring-offset-base-200;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
User Menu Button - Smooth Centering Transition
|
||||
============================================ */
|
||||
|
||||
/* User menu button transitions smoothly to center */
|
||||
.user-menu-button {
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
/* In collapsed state, center avatar under logo
|
||||
- Avatar is 32px (w-8), center it in 64px sidebar
|
||||
- (64px - 32px) / 2 = 16px padding → avatar center at 32px (same as logo center) */
|
||||
[data-sidebar-expanded="false"] .sidebar .user-menu-button {
|
||||
@apply gap-0;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
User Menu Button - Hover Ring on Avatar
|
||||
============================================ */
|
||||
|
||||
/* Smooth transition for avatar ring effects */
|
||||
.user-menu-button .avatar > div {
|
||||
@apply transition-all duration-200;
|
||||
}
|
||||
|
||||
/* Hover ring appears on the avatar when button is hovered */
|
||||
.user-menu-button:hover .avatar > div {
|
||||
@apply ring-1 ring-neutral ring-offset-1 ring-offset-base-200;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
|
|
|
|||
|
|
@ -530,3 +530,4 @@ The DaisyUI drawer pattern provides:
|
|||
|
||||
**Recommended approach**: Use `lg:drawer-open` for desktop with hidden mobile toggle for best responsive experience.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -744,3 +744,4 @@ role="menubar", role="menuitem", role="none", role="status"
|
|||
|
||||
**Ende des Berichts**
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1248,3 +1248,4 @@ if (localStorage.getItem('sidebar-expanded') === 'false') {
|
|||
**Ende der Spezifikation**
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ defmodule MvWeb.Layouts.Sidebar do
|
|||
<button
|
||||
type="button"
|
||||
tabindex="0"
|
||||
class="flex items-center justify-center w-full p-2 rounded-lg hover:bg-base-300 tooltip tooltip-right focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
|
||||
class="flex items-center w-full p-2 rounded-lg hover:bg-base-300 tooltip tooltip-right focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
|
||||
data-tip={@label}
|
||||
aria-haspopup="menu"
|
||||
aria-label={@label}
|
||||
|
|
@ -251,18 +251,18 @@ defmodule MvWeb.Layouts.Sidebar do
|
|||
assigns = assign(assigns, :user_id, user_id)
|
||||
|
||||
~H"""
|
||||
<div class="dropdown dropdown-top dropdown-right w-full">
|
||||
<div class="dropdown dropdown-top dropdown-end w-full">
|
||||
<button
|
||||
type="button"
|
||||
tabindex="0"
|
||||
class="btn btn-ghost w-full justify-start gap-3 px-4 h-12 min-h-12 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
|
||||
class="user-menu-button flex items-center w-full justify-start gap-3 px-4 h-12 min-h-12 rounded-lg cursor-pointer focus:outline-none"
|
||||
aria-label={gettext("User menu")}
|
||||
aria-haspopup="menu"
|
||||
>
|
||||
<!-- Avatar: Zentriert, erste Buchstabe -->
|
||||
<!-- Avatar: Placeholder with first letter -->
|
||||
<div class="avatar placeholder shrink-0">
|
||||
<div class="w-8 h-8 rounded-full bg-neutral text-neutral-content flex items-center justify-center">
|
||||
<span class="text-sm font-semibold leading-none flex items-center justify-center" style="margin-top: 1px;">
|
||||
<div class="w-8 h-8 rounded-full bg-neutral text-neutral-content">
|
||||
<span class="text-sm font-semibold">
|
||||
{@first_letter}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -712,19 +712,19 @@ defmodule MvWeb.Layouts.SidebarTest do
|
|||
html = render_sidebar(authenticated_assigns(false))
|
||||
|
||||
# Toggle button has onclick handler
|
||||
assert html =~ ~s(onclick="toggleSidebar()")
|
||||
assert html =~ ~r/onclick="toggleSidebar\(\)"/
|
||||
end
|
||||
|
||||
test "no duplicate IDs in layout" do
|
||||
html = render_sidebar(authenticated_assigns())
|
||||
|
||||
# Check that main-sidebar ID appears only once
|
||||
id_count = html |> String.split(~s(id="main-sidebar")) |> length() |> Kernel.-(1)
|
||||
id_count = html |> String.split(~r/id="main-sidebar"/) |> length() |> Kernel.-(1)
|
||||
assert id_count == 1, "main-sidebar ID should appear exactly once"
|
||||
|
||||
# Check that sidebar-toggle ID appears only once (if present)
|
||||
if html =~ ~s(id="sidebar-toggle") do
|
||||
toggle_count = html |> String.split(~s(id="sidebar-toggle")) |> length() |> Kernel.-(1)
|
||||
if html =~ ~r/id="sidebar-toggle"/ do
|
||||
toggle_count = html |> String.split(~r/id="sidebar-toggle"/) |> length() |> Kernel.-(1)
|
||||
assert toggle_count == 1, "sidebar-toggle ID should appear exactly once"
|
||||
end
|
||||
end
|
||||
|
|
@ -844,7 +844,7 @@ defmodule MvWeb.Layouts.SidebarTest do
|
|||
assert has_class?(html, "dropdown-content")
|
||||
|
||||
# Should have both Profile and Logout links
|
||||
assert html =~ ~s(href="/sign-out")
|
||||
assert html =~ "sign-out"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue