From 31e7a67a0def4983b09c7b6f6edf68a605010de3 Mon Sep 17 00:00:00 2001 From: claude-owner Date: Sat, 30 May 2026 20:13:44 +0900 Subject: [PATCH] feat(symbol-page): aria-pressed PeriodTabs + sticky orderbook in 1D mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PeriodTabs (reviewer 488fb32 concern): - Drop role=tablist/tab/aria-selected. These imply a full ARIA tab pattern (tabpanel, aria-controls, roving tabIndex, internal Arrow focus traversal) which we don't implement — page-level left/right keys drive period change instead. Switch to plain button group with aria-pressed={active}, which accurately describes a segmented toggle. Comment updated to match. OrderbookPanel sticky (new slice): - Add optional sticky prop. When true, panel uses 'sticky top-4' with a slightly heavier bg-zinc-900/80 + backdrop-blur so it stays legible over the panels scrolling behind it. - page.tsx passes sticky={isIntraday} — only 1D (10m bars) mode benefits, since orderbook timeliness drops on daily+ charts and the fixed slot would harm sidebar layout stability there. --- web/app/[code]/page.tsx | 2 +- web/components/OrderbookPanel.tsx | 15 +++++++++++++-- web/components/PeriodTabs.tsx | 9 +++++---- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/web/app/[code]/page.tsx b/web/app/[code]/page.tsx index 5e410de..df7eb68 100644 --- a/web/app/[code]/page.tsx +++ b/web/app/[code]/page.tsx @@ -253,7 +253,7 @@ export default function CodePage({ params }: { params: { code: string } }) {
- + diff --git a/web/components/OrderbookPanel.tsx b/web/components/OrderbookPanel.tsx index b61b691..73f9de8 100644 --- a/web/components/OrderbookPanel.tsx +++ b/web/components/OrderbookPanel.tsx @@ -16,11 +16,16 @@ import { api, type OrderbookLevel, type OrderbookResponse } from "../lib/api"; type Props = { code: string; + // 1D(10분봉) 모드일 때만 sticky 로 띄움 — 종목 페이지가 길어 스크롤해도 매수/매도 호가가 + // 시야에 남도록. 일봉 이상에선 호가의 실시간 가치가 낮아 일반 흐름으로 두는 게 사이드바 + // 다른 패널(PriceTargets/AlertsPanel/InvestmentNote/RelatedStocks) 의 위치 안정성을 해치지 + // 않음. + sticky?: boolean; }; const POLL_MS = 10_000; -export function OrderbookPanel({ code }: Props) { +export function OrderbookPanel({ code, sticky = false }: Props) { const [data, setData] = useState(null); const [err, setErr] = useState(null); const [loading, setLoading] = useState(true); @@ -51,7 +56,13 @@ export function OrderbookPanel({ code }: Props) { }, [code]); return ( -
+
호가 diff --git a/web/components/PeriodTabs.tsx b/web/components/PeriodTabs.tsx index 31d6d90..b48e421 100644 --- a/web/components/PeriodTabs.tsx +++ b/web/components/PeriodTabs.tsx @@ -43,10 +43,12 @@ export function PeriodTabs({ value, onChange }: Props) { // 페이지에서 "지금 어느 기간이 선택돼 있는지" 한눈에 안 들어왔음. // 한국 컬러 상승 톤(rose-500) 으로 칠해서 zinc 버튼군 사이에서 즉시 식별. 다른 모듈의 활성/positive // 상태(목표가 라인, 등락 양수 등) 도 같은 rose 계열이라 톤 일관성 유지. - // aria-pressed: 토글 그룹 의미 명시 — 스크린리더가 선택 상태 읽어줌. + // ARIA: 이건 tabpanel 을 가진 진짜 탭이 아니라 차트 기간 segmented control 임. + // role=tablist/tab 을 붙이면 스크린리더가 aria-controls·roving tabIndex·Arrow focus 이동 같은 + // ARIA 탭 패턴을 기대하는데 여기엔 그 인프라가 없음 (←/→ 는 페이지 전역 단축키로 처리). 단순 + // 버튼 그룹 + aria-pressed 가 정확한 표현. return (
@@ -56,8 +58,7 @@ export function PeriodTabs({ value, onChange }: Props) {