feat(ui): wrap header actions in dialog for small screens

This commit is contained in:
Julien Oculi 2024-02-15 15:24:53 +01:00
parent ae642634c6
commit 7ac22f8375
5 changed files with 87 additions and 7 deletions

View file

@ -1,6 +1,7 @@
import { asset } from '$fresh/runtime.ts' import { asset } from '$fresh/runtime.ts'
import SearchBox from '../islands/SearchBox.tsx' import SearchBox from '../islands/SearchBox.tsx'
import ThemePicker from '../islands/ThemePicker.tsx' import ThemePicker from '../islands/ThemePicker.tsx'
import MoreBox from '../islands/MoreBox.tsx'
export function Header() { export function Header() {
return ( return (
@ -63,7 +64,15 @@ export function Header() {
</li> </li>
</nav> </nav>
<SearchBox /> <SearchBox />
<MoreBox>
<ThemePicker /> <ThemePicker />
<a href='/profil'>
<i class='ri-user-line'></i>
</a>
<button>
<i class='ri-bard-line'></i>
</button>
</MoreBox>
</div> </div>
</header> </header>
) )

48
islands/MoreBox.css Normal file
View file

@ -0,0 +1,48 @@
.islands__more_box__dialog {
gap: var(--_gap);
color: var(--_font-color);
align-items: center;
}
.islands__more_box__dialog[open] {
display: flex;
flex-direction: column;
padding: var(--_gap);
border: var(--_border-size) solid currentColor;
background: var(--_background-image) repeat top left / 800px;
background-color: var(--_background-color);
&::backdrop {
backdrop-filter: blur(var(--_blur));
}
}
.islands__more_box__button {
background: transparent;
border: none;
outline: none;
border: var(--_border-size) solid transparent;
color: var(--_font-color);
&:focus-visible,
&:hover {
border-color: currentColor;
}
}
@media (width > 800px) {
.islands__more_box__dialog {
display: flex;
padding: 0;
border: none;
margin: 0;
position: static;
height: 100%;
background-color: transparent;
align-self: center;
}
.islands__more_box__button {
display: none;
}
}

28
islands/MoreBox.tsx Normal file
View file

@ -0,0 +1,28 @@
import { VNode } from 'preact'
import { useEffect, useRef } from 'preact/hooks'
export default function MoreBox({ children }: { children: VNode | VNode[] }) {
const dialog = useRef<HTMLDialogElement>(null)
useEffect(() => {
dialog.current?.addEventListener('click', (event) => {
if (event.target === dialog.current) {
dialog.current?.close()
}
})
}, [])
return (
<>
<button
class='islands__more_box__button'
onClick={() => dialog.current?.showModal()}
>
<i class='ri-more-2-line'></i>
</button>
<dialog class='islands__more_box__dialog' ref={dialog}>
{children}
</dialog>
</>
)
}

View file

@ -26,10 +26,4 @@
font-weight: normal; font-weight: normal;
line-height: normal; line-height: normal;
} }
@media (width < 800px) {
& select {
width: 0;
}
}
} }

View file

@ -10,3 +10,4 @@
@import url('../../components/MemberCard.css'); @import url('../../components/MemberCard.css');
@import url('../../islands/ThemePicker.css'); @import url('../../islands/ThemePicker.css');
@import url('../../islands/SearchBox.css'); @import url('../../islands/SearchBox.css');
@import url('../../islands/MoreBox.css');