LoVisual/frontend/src/features/clickgui/screens/ModulesScreen.tsx
loki5512344 e00ea8eb11
feat: frontend perf and a11y pass, plus mod visuals, hero main menu, Simple Voice Chat and vanilla chat autocomplete
Frontend:
- replace the i18next stack with a small typed i18n module
- hero clouds removed, llms.txt, HUD widget ARIA fixes and tests

Mod:
- TargetESP constellation mode; tracker and colors extracted
- JumpCircles: 7 new shapes, shared animation and color pipeline
- KillEffect blood mode with Burst/Fountain/Ring/Spray styles
- main menu: menuLayout setting (orbs/hero) and hero screen
- Simple Voice Chat soft integration: VoiceChat module and HUD panel
- renderer/quick: static Draw facade with glass outline
- vanilla chat: Baritone-style autocomplete popup for the % command prefix
2026-10-01 21:29:54 +02:00

56 lines
2 KiB
TypeScript

import type { Dispatch } from 'react'
import { useTranslation } from '@shared/i18n/react'
import type { GuiAction, GuiState } from '../demo'
import { Icon } from '../parts/Glyphs'
import { type Category, CATEGORIES } from '../parts/modules'
type Props = { state: GuiState; dispatch: Dispatch<GuiAction> }
/** `ModulesMenuScreen`: the four liquid-glass category panels, side by side. */
export function ModulesScreen({ state, dispatch }: Props) {
const { t } = useTranslation('clickgui')
return (
<div className="lv-gui-panels" role="list" aria-label={t('categories')}>
{CATEGORIES.map((c) => (
<Panel key={c.id} category={c} state={state} dispatch={dispatch} />
))}
</div>
)
}
function Panel({ category, state, dispatch }: { category: Category } & Props) {
const { t } = useTranslation('clickgui')
const titleId = `lv-gui-panel-${category.id}`
return (
<div role="listitem" className="lv-gui-panel" data-category={category.id} aria-labelledby={titleId}>
<header className="lv-gui-panel-head">
<h2 id={titleId} className="lv-gui-panel-title">
{category.name}
</h2>
<Icon name={category.id} className="lv-gui-panel-icon" />
</header>
<ul className="lv-gui-rows">
{category.modules.map((m) => {
const on = Boolean(state.enabled[m.name])
return (
<li key={m.name}>
<button
type="button"
className="lv-gui-row"
data-on={on}
data-demo={`module:${m.name}`}
aria-pressed={on}
title={t('module', { name: m.name })}
onClick={() => dispatch({ type: 'toggle', module: m.name })}
onContextMenu={(e) => e.preventDefault()}
>
<span className="lv-gui-row-name">{m.name}</span>
{on && <Icon name="check" className="lv-gui-row-check" />}
</button>
</li>
)
})}
</ul>
</div>
)
}