fix(andreknie.de): improve mobile dock and resource requests

This commit is contained in:
2026-07-28 20:54:08 +02:00
parent 0459daa074
commit 8236cce85c
12 changed files with 219 additions and 61 deletions
@@ -114,6 +114,23 @@
}
@media (max-width: 600px) {
.dock { gap: 6px; padding: 6px 8px; }
.dock-item { width: 38px; height: 38px; }
.dock-container {
bottom: max(12px, env(safe-area-inset-bottom));
max-width: calc(100vw - 24px);
}
.dock {
gap: 6px;
padding: 6px 8px;
max-width: 100%;
}
.dock-item-wrapper-secondary {
display: none;
}
.dock-item {
width: 44px;
height: 44px;
}
}
@@ -10,22 +10,27 @@ export default function BottomDock() {
{ label: 'Home', path: '/', icon: <Home size={20} /> },
{ label: 'Artikel', path: '/artikel', icon: <Newspaper size={20} /> },
{ label: 'Kniepunkt', path: '/kniepunkt', icon: <span style={{ fontWeight: 800, fontSize: '1.2rem', fontFamily: 'serif' }}>K</span> },
{ label: 'Podcast', path: '/podcast', icon: <Mic size={20} /> },
{ label: 'Podcast', path: '/podcast', icon: <Mic size={20} />, secondary: true },
{ label: 'Speaking', path: '/speaking', icon: <MessageSquare size={20} /> },
{ label: 'Beratung', path: '/consulting', icon: <Briefcase size={20} /> },
{ label: 'Über mich', path: '/ueber-mich', icon: <User size={20} /> },
{ label: 'Beratung', path: '/consulting', icon: <Briefcase size={20} />, secondary: true },
{ label: 'Über mich', path: '/ueber-mich', icon: <User size={20} />, secondary: true },
{ label: 'Kontakt', path: '/kontakt', icon: <Mail size={20} /> },
]
return (
<div className="dock-container">
<nav className="dock">
<nav className="dock" aria-label="Schnellnavigation">
{items.map((item) => {
const isActive = location.pathname === item.path
return (
<div className="dock-item-wrapper" key={item.path}>
<div className={`dock-item-wrapper${item.secondary ? ' dock-item-wrapper-secondary' : ''}`} key={item.path}>
<span className="dock-tooltip">{item.label}</span>
<Link to={item.path} className={`dock-item ${isActive ? 'active' : ''}`}>
<Link
to={item.path}
className={`dock-item ${isActive ? 'active' : ''}`}
aria-label={item.label}
aria-current={isActive ? 'page' : undefined}
>
{item.icon}
</Link>
</div>
@@ -0,0 +1,30 @@
import React from 'react'
import { describe, expect, it } from 'vitest'
import { render } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import { readFileSync } from 'fs'
import { join } from 'path'
import BottomDock from './BottomDock'
describe('BottomDock', () => {
it('keeps secondary links available on desktop and marks them for mobile hiding', () => {
const { container } = render(
<MemoryRouter initialEntries={['/']}>
<BottomDock />
</MemoryRouter>,
)
expect(container.querySelectorAll('.dock-item')).toHaveLength(8)
expect(container.querySelectorAll('.dock-item-wrapper-secondary')).toHaveLength(3)
expect(container.querySelectorAll('.dock-item[aria-label]')).toHaveLength(8)
})
it('reserves mobile space and keeps touch targets at least 44 pixels', () => {
const css = readFileSync(join(process.cwd(), 'src', 'components', 'BottomDock.css'), 'utf-8')
const mobileRule = css.match(/@media \(max-width: 600px\) \{([\s\S]*)\}\s*$/)
expect(mobileRule?.[1]).toContain('dock-item-wrapper-secondary')
expect(mobileRule?.[1]).toMatch(/width: 44px/)
expect(mobileRule?.[1]).toMatch(/height: 44px/)
})
})