diff --git a/src/modules/energy/HydrogenDaily.tsx b/src/modules/energy/HydrogenDaily.tsx index 21c50cc..68fd432 100644 --- a/src/modules/energy/HydrogenDaily.tsx +++ b/src/modules/energy/HydrogenDaily.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Building2, ChevronRight, Fuel, Plug, ReceiptText, TrendingUp, Truck, UserRound, X } from 'lucide-react'; import { motion, AnimatePresence } from 'motion/react'; import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer, Cell, Tooltip, ReferenceLine } from 'recharts'; @@ -29,6 +29,8 @@ const VEHICLE_SCOPE_OPTIONS: readonly AnalysisScopeOption[] = [ { id: 'external', label: '外部车辆' }, ]; +const HYDROGEN_ORDERS_ID = 'hydrogen-orders'; + export default function HydrogenDaily() { const [drillContext, setDrillContext] = useState(() => ( parseHydrogenDrillContext(window.location.search) @@ -48,6 +50,7 @@ export default function HydrogenDaily() { const [rows, setRows] = useState(null); const [error, setError] = useState(null); const [retryKey, setRetryKey] = useState(0); + const orderTriggerRef = useRef(null); const effectiveRange = useMemo(() => normalizeDateRange(dateRange.start, dateRange.end), [dateRange.start, dateRange.end]); const selectedStationId = drillContext.level === 'station' ? drillContext.stationId : undefined; @@ -159,6 +162,10 @@ export default function HydrogenDaily() { }; const openOrders = (date: string) => { + const activeElement = document.activeElement; + if (activeElement instanceof HTMLElement || activeElement instanceof SVGElement) { + orderTriggerRef.current = activeElement; + } commitDrillContext({ ...drillContext, vehicleScope, @@ -166,7 +173,15 @@ export default function HydrogenDaily() { endDate: effectiveRange.end, selectedDate: date, orderPage: undefined, - }, 'push'); + }, selectedDate === date ? 'replace' : 'push'); + window.requestAnimationFrame(() => { + const orders = document.getElementById(HYDROGEN_ORDERS_ID); + orders?.focus({ preventScroll: true }); + orders?.scrollIntoView({ + behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth', + block: 'start', + }); + }); }; const closeOrders = () => { @@ -178,6 +193,7 @@ export default function HydrogenDaily() { selectedDate: undefined, orderPage: undefined, }, 'replace'); + window.requestAnimationFrame(() => orderTriggerRef.current?.focus()); }; const changeOrderPage = useCallback((page: number, mode: 'push' | 'replace') => { @@ -375,7 +391,8 @@ export default function HydrogenDaily() { className={item.totalKg > 0 ? 'cursor-pointer outline-none focus:stroke-blue-700 focus:stroke-2' : undefined} role={item.totalKg > 0 ? 'button' : undefined} tabIndex={item.totalKg > 0 ? 0 : -1} - aria-pressed={item.totalKg > 0 ? selectedDate === item.date : undefined} + aria-expanded={item.totalKg > 0 ? selectedDate === item.date : undefined} + aria-controls={item.totalKg > 0 ? HYDROGEN_ORDERS_ID : undefined} aria-label={`${item.date},加氢量 ${item.totalKg.toLocaleString('zh-CN', { maximumFractionDigits: 2 })} Kg${item.totalKg > 0 ? `,查看${orderScopeLabel}加氢订单` : ',无可下钻订单'}`} onClick={item.totalKg > 0 ? () => openOrders(item.date) : undefined} onKeyDown={item.totalKg > 0 @@ -457,6 +474,8 @@ export default function HydrogenDaily() { disabled={r.totalKg <= 0} className="ml-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-lg text-slate-400 hover:bg-blue-100 hover:text-blue-700 disabled:cursor-not-allowed disabled:opacity-25" aria-label={`查看 ${r.date} 加氢订单`} + aria-expanded={selectedDate === r.date} + aria-controls={HYDROGEN_ORDERS_ID} title="查看当日订单" > diff --git a/src/modules/energy/HydrogenOrders.tsx b/src/modules/energy/HydrogenOrders.tsx index 9b5bb48..d6732a8 100644 --- a/src/modules/energy/HydrogenOrders.tsx +++ b/src/modules/energy/HydrogenOrders.tsx @@ -73,7 +73,11 @@ export default function HydrogenOrders({ : ''; return ( -
+