fix(web): крупные стрелки устройств и панели, не уезжающие за экран
- стрелки настроек микрофона, камеры и наушников стали прямоугольниками во всю высоту основной кнопки (32 px) и шириной около трети кнопки: по ним легко попасть, группы не наслаиваются и не выходят за панель (сайдбар расширен до 256 px, у групп фиксированная ширина 36 px); - поповеры и меню теперь позиционируются от рабочей области: новая `useAnchoredPosition` прижимает панель к краям окна, выбирает сторону с большим запасом места и ограничивает высоту, а содержимое прокручивается — подписи устройств и слайдер громкости больше не обрезаются; - тесты: геометрия группы стрелки, открытие меню и ограничение положения панели в пределах окна (289 тестов Vitest).
This commit is contained in:
@@ -162,7 +162,7 @@ export default function AppLayout() {
|
||||
*/}
|
||||
<div
|
||||
data-testid="app-sidebar-column"
|
||||
className="flex w-60 shrink-0 flex-col border-r border-border/40 bg-surface-1"
|
||||
className="flex w-64 shrink-0 flex-col border-r border-border/40 bg-surface-1"
|
||||
>
|
||||
{isFriends ? (
|
||||
<FriendsSidebar channelId={dmChannelId} />
|
||||
|
||||
@@ -76,10 +76,13 @@ function PanelControl({
|
||||
children,
|
||||
}: PanelControlProps) {
|
||||
const anchorRef: RefObject<HTMLButtonElement | null> = useRef(null);
|
||||
// Группа «стрелка + кнопка»: поповер прижимается к её краю.
|
||||
const groupRef: RefObject<HTMLDivElement | null> = useRef(null);
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center">
|
||||
{/* Узкая стрелка: панель шириной 240px, место здесь на счету. */}
|
||||
<div ref={groupRef} className="relative flex h-8 w-9 shrink-0 items-stretch gap-0">
|
||||
{/* Прямоугольник-стрелка во всю высоту основной кнопки: по нему легко
|
||||
попасть мышью, ширина — около трети кнопки (жалоба пользователя). */}
|
||||
<button
|
||||
type="button"
|
||||
aria-haspopup="dialog"
|
||||
@@ -87,9 +90,11 @@ function PanelControl({
|
||||
aria-label={menuLabel}
|
||||
title={menuLabel}
|
||||
onClick={onOpenMenu}
|
||||
className="rounded-[var(--radius-sm)] px-0.5 text-[8px] leading-none text-fg-muted transition-colors duration-[var(--duration-fast)] hover:bg-surface-3 hover:text-fg active:scale-95"
|
||||
className="flex w-3 shrink-0 items-center justify-center rounded-l-[var(--radius-sm)] text-fg-muted transition-colors duration-[var(--duration-fast)] hover:bg-surface-3 hover:text-fg active:bg-surface-3"
|
||||
>
|
||||
▾
|
||||
<svg aria-hidden="true" viewBox="0 0 8 6" className="h-1.5 w-2 fill-current">
|
||||
<path d="M0 0h8L4 6z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
ref={anchorRef}
|
||||
@@ -98,7 +103,7 @@ function PanelControl({
|
||||
aria-label={toggleLabel}
|
||||
title={toggleLabel}
|
||||
onClick={onToggle}
|
||||
className={`rounded-[var(--radius-sm)] px-1 py-1 text-base leading-none transition-[color,background-color,transform] duration-[var(--duration-fast)] hover:bg-surface-3 active:scale-95 ${
|
||||
className={`flex min-w-0 flex-1 items-center justify-center rounded-r-[var(--radius-sm)] px-1 text-base leading-none transition-[color,background-color,transform] duration-[var(--duration-fast)] hover:bg-surface-3 active:scale-95 ${
|
||||
enabled ? 'text-fg' : 'text-danger'
|
||||
}`}
|
||||
>
|
||||
@@ -108,9 +113,9 @@ function PanelControl({
|
||||
<Popover
|
||||
open={open}
|
||||
label={menuLabel}
|
||||
anchorRef={anchorRef}
|
||||
anchorRef={groupRef}
|
||||
align="right"
|
||||
className="w-64 max-w-[70vw]"
|
||||
className="w-64 max-w-[80vw]"
|
||||
onClose={onCloseMenu}
|
||||
>
|
||||
{children}
|
||||
@@ -222,7 +227,7 @@ export function UserPanel() {
|
||||
className="relative border-t border-border/40 bg-surface-2/80 p-2"
|
||||
>
|
||||
{/* Подложка панели: слева профиль, справа кнопки устройств и настроек. */}
|
||||
<div className="flex items-center gap-0.5 rounded-[var(--radius-md)] border border-border/60 bg-surface-1 px-1.5 py-1.5">
|
||||
<div className="flex items-stretch gap-1 overflow-hidden rounded-[var(--radius-md)] border border-border/60 bg-surface-1 px-1.5 py-1.5">
|
||||
<button
|
||||
ref={profileRef}
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user