feat: implement standard-compliant sidebar with comprehensive tests
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Implement a new sidebar component based on DaisyUI Drawer pattern without custom CSS variants. The sidebar supports desktop (expanded/collapsed states) and mobile (overlay drawer) with full accessibility compliance. Sidebar Implementation: - Refactor sidebar component with sidebar_header, menu_item, menu_group, sidebar_footer sub-components - Add logo (mila.svg) with size-8 (32px) always visible - Implement toggle button with icon swap (chevron-left/right) for desktop - Add nested menu support with details/summary (expanded) and dropdown (collapsed) patterns - Implement footer with language selector (expanded-only), theme toggle, and user menu with avatar - Update layouts.ex to use drawer pattern with data-sidebar-expanded attribute for state management CSS & JavaScript: - Add CSS styles for sidebar state management via data-attribute selectors - Implement SidebarState JavaScript hook for localStorage persistence - Add smooth width transitions (w-64 ↔ w-16) for desktop collapsed state - Add CSS classes for expanded-only, menu-label, and icon visibility Documentation: - Add sidebar-analysis-current-state.md: Analysis of current implementation - Add sidebar-requirements-v2.md: Complete specification for new sidebar - Add daisyui-drawer-pattern.md: DaisyUI pattern documentation - Add umsetzung-sidebar.md: Step-by-step implementation guide Testing: - Add comprehensive component tests for all sidebar sub-components - Add integration tests for sidebar state management and mobile drawer - Extend accessibility tests (ARIA labels, roles, keyboard navigation) - Add regression tests for duplicate IDs, hover effects, and tooltips - Ensure full test coverage per specification requirements
This commit is contained in:
parent
b0097ab99d
commit
16ca4efc03
10 changed files with 5439 additions and 194 deletions
|
|
@ -9,7 +9,6 @@ defmodule MvWeb.Layouts do
|
|||
"""
|
||||
use MvWeb, :html
|
||||
use Gettext, backend: MvWeb.Gettext
|
||||
import MvWeb.Layouts.Navbar
|
||||
import MvWeb.Layouts.Sidebar
|
||||
|
||||
embed_templates "layouts/*"
|
||||
|
|
@ -44,21 +43,39 @@ defmodule MvWeb.Layouts do
|
|||
assigns = assign(assigns, :club_name, club_name)
|
||||
|
||||
~H"""
|
||||
<div class="drawer">
|
||||
<input id="main-drawer" type="checkbox" class="drawer-toggle" />
|
||||
<div class="drawer-content">
|
||||
<%= if @current_user do %>
|
||||
<.navbar current_user={@current_user} />
|
||||
<% end %>
|
||||
<main class="px-4 py-20 sm:px-6 lg:px-16">
|
||||
<div class="mx-auto space-y-4 max-full">
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<%= if @current_user do %>
|
||||
<div id="app-layout" class="drawer lg:drawer-open" data-sidebar-expanded="true" phx-hook="SidebarState">
|
||||
<input id="mobile-drawer" type="checkbox" class="drawer-toggle" />
|
||||
|
||||
<.sidebar current_user={@current_user} club_name={@club_name} />
|
||||
</div>
|
||||
<div class="drawer-content flex flex-col relative z-0">
|
||||
<!-- Mobile Header (only visible on mobile) -->
|
||||
<header class="lg:hidden sticky top-0 z-10 navbar bg-base-100 shadow-sm">
|
||||
<label for="mobile-drawer" class="btn btn-square btn-ghost" aria-label={gettext("Open navigation menu")}>
|
||||
<.icon name="hero-bars-3" class="size-6" aria-hidden="true" />
|
||||
</label>
|
||||
<span class="font-bold">{@club_name}</span>
|
||||
</header>
|
||||
|
||||
<!-- Main Content (shared between mobile and desktop) -->
|
||||
<main class="px-4 py-8 sm:px-6 lg:px-8">
|
||||
<div class="mx-auto space-y-4 max-full">
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div class="drawer-side z-40">
|
||||
<.sidebar current_user={@current_user} club_name={@club_name} mobile={false} />
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<!-- Not logged in -->
|
||||
<main class="px-4 py-8 sm:px-6">
|
||||
<div class="mx-auto space-y-4 max-full">
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</main>
|
||||
<% end %>
|
||||
|
||||
<.flash_group flash={@flash} />
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue