Files
makelore/src/components/layout/ClassroomSidebarResizer.tsx
T

55 lines
2.3 KiB
TypeScript

import { useRef } from 'react';
import { useSettingsStore } from '@/stores/settings';
import {
CLASSROOM_SIDEBAR_DEFAULT_WIDTH,
CLASSROOM_SIDEBAR_MIN_WIDTH,
CLASSROOM_SIDEBAR_MAX_WIDTH,
normalizeClassroomSidebarWidth,
} from '@/lib/classroom-layout';
export function ClassroomSidebarResizer() {
const width = useSettingsStore((state) => normalizeClassroomSidebarWidth(state.classroomSidebarWidth));
const setWidth = useSettingsStore((state) => state.setClassroomSidebarWidth);
const drag = useRef<{ pointerId: number; x: number; width: number } | null>(null);
return <div
role="separator"
aria-label="调整左侧功能栏宽度"
aria-orientation="vertical"
aria-controls="classroom-sidebar"
aria-valuemin={CLASSROOM_SIDEBAR_MIN_WIDTH}
aria-valuemax={CLASSROOM_SIDEBAR_MAX_WIDTH}
aria-valuenow={width}
aria-valuetext={`${width} 像素`}
title="拖动调整宽度,双击恢复默认"
tabIndex={0}
className="no-drag absolute inset-y-0 right-0 z-10 w-1.5 cursor-col-resize touch-none select-none transition-colors hover:bg-[#82986755] focus-visible:bg-[#82986755] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[#71845f]"
onDoubleClick={() => setWidth(CLASSROOM_SIDEBAR_DEFAULT_WIDTH)}
onPointerDown={(event) => {
if (event.button !== 0) return;
event.preventDefault();
event.currentTarget.setPointerCapture(event.pointerId);
drag.current = { pointerId: event.pointerId, x: event.clientX, width };
}}
onPointerMove={(event) => {
if (drag.current?.pointerId !== event.pointerId) return;
setWidth(drag.current.width + event.clientX - drag.current.x);
}}
onPointerUp={(event) => {
if (drag.current?.pointerId !== event.pointerId) return;
drag.current = null;
event.currentTarget.releasePointerCapture(event.pointerId);
}}
onLostPointerCapture={() => { drag.current = null; }}
onPointerCancel={() => { drag.current = null; }}
onKeyDown={(event) => {
const next = event.key === 'ArrowRight' ? width + 8
: event.key === 'ArrowLeft' ? width - 8
: event.key === 'Home' ? CLASSROOM_SIDEBAR_MIN_WIDTH
: event.key === 'End' ? CLASSROOM_SIDEBAR_MAX_WIDTH : null;
if (next === null) return;
event.preventDefault();
setWidth(next);
}}
/>;
}