mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 07:40:59 +00:00
4d00858b8a
The home chat's trip list opened before its trips had loaded, so the focus stayed on its button and no trip could be reached by keyboard; the first trip now takes the focus once the list is there. The header's menu says whether it is open, and closed by Escape or a pick it hands the focus back to its button, so the next Escape closes the window again. The open chat in the history list is announced as the current one.
41 lines
2.0 KiB
TypeScript
41 lines
2.0 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
import { Check } from 'lucide-react'
|
|
|
|
/** An entry in a packing popover: icon column, label, a tick on the current choice (the shared look is in packingPopoverStyles.ts). */
|
|
interface PopoverItemProps {
|
|
icon: ReactNode
|
|
label: string
|
|
onClick: () => void
|
|
active?: boolean
|
|
/** The entry is the one open now (a chat in a history list), said so to a screen reader too. */
|
|
current?: boolean
|
|
danger?: boolean
|
|
/** A secondary line, such as Add bag, in the faint text colour. */
|
|
muted?: boolean
|
|
/** What sits at the right end; the current choice gets a tick by default. */
|
|
trailing?: ReactNode
|
|
}
|
|
|
|
export function PopoverItem({ icon, label, onClick, active = false, current = false, danger = false, muted = false, trailing }: PopoverItemProps) {
|
|
const tone = danger ? '#ef4444' : muted ? 'var(--text-faint)' : 'var(--text-primary)'
|
|
return (
|
|
<button type="button"
|
|
onClick={onClick}
|
|
aria-current={current || undefined}
|
|
style={{
|
|
display: 'flex', alignItems: 'center', gap: 9, width: '100%',
|
|
padding: '8px 10px', borderRadius: 9, border: 'none', cursor: 'pointer',
|
|
background: active ? 'var(--bg-tertiary)' : 'none',
|
|
color: tone,
|
|
fontFamily: 'inherit', fontSize: 'calc(12.5px * var(--fs-scale-body, 1))', fontWeight: 500, textAlign: 'start',
|
|
}}
|
|
onMouseEnter={e => { if (!active) e.currentTarget.style.background = danger ? 'rgba(239,68,68,0.1)' : 'var(--bg-tertiary)' }}
|
|
onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'none' }}
|
|
>
|
|
<span style={{ width: 16, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, color: danger ? '#ef4444' : 'var(--text-muted)' }}>{icon}</span>
|
|
<span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{label}</span>
|
|
{trailing ?? (active ? <Check size={13} style={{ color: 'var(--text-muted)', flexShrink: 0 }} /> : null)}
|
|
</button>
|
|
)
|
|
}
|