refactor(web): extract prefetch slider into reusable RdSlider component

This commit is contained in:
2026-09-08 21:31:20 +08:00
parent 472e58bec9
commit 3178c2802f
2 changed files with 46 additions and 19 deletions
+37
View File
@@ -0,0 +1,37 @@
/** 阅读器主题内的滑条配置项:说明 + 整数档位滑条 + 锚点刻度. */
export function RdSlider({
label,
ariaLabel,
min,
max,
value,
onChange,
}: {
label: string;
ariaLabel: string;
min: number;
max: number;
value: number;
onChange: (v: number) => void;
}) {
return (
<div className="px-2.5 pb-1.5 pt-2">
<div className="mb-1 text-sm">{label}</div>
<input
type="range"
min={min}
max={max}
step={1}
value={value}
aria-label={ariaLabel}
className="rd-range"
onChange={(e) => onChange(Number(e.target.value))}
/>
<div className="flex justify-between px-1 text-[10px] tabular-nums opacity-50" aria-hidden="true">
{Array.from({ length: max - min + 1 }, (_, i) => (
<span key={i}>{min + i}</span>
))}
</div>
</div>
);
}
+9 -19
View File
@@ -5,6 +5,7 @@ import { useEffect, useMemo, useRef, useState, type MouseEvent } from "react";
import { api, formatPageUrl } from "../api/client"; import { api, formatPageUrl } from "../api/client";
import { btn } from "../components/ui"; import { btn } from "../components/ui";
import { BookmarksTab } from "../components/Bookmarks"; import { BookmarksTab } from "../components/Bookmarks";
import { RdSlider } from "../components/rd-slider";
import { ReaderNav, type NavTab } from "../components/reader-nav"; import { ReaderNav, type NavTab } from "../components/reader-nav";
import { fetchObjectUrl } from "../lib/authImage"; import { fetchObjectUrl } from "../lib/authImage";
import { useProgressSaver, type ReaderProps } from "../lib/useProgress"; import { useProgressSaver, type ReaderProps } from "../lib/useProgress";
@@ -395,25 +396,14 @@ export default function CbzReader({ book, initialLocator, initialPercent, chrome
</DropdownMenu.ItemIndicator> </DropdownMenu.ItemIndicator>
</DropdownMenu.CheckboxItem> </DropdownMenu.CheckboxItem>
{locked && ( {locked && (
<div className="px-2.5 pb-1.5 pt-2"> <RdSlider
<div className="mb-1 text-sm">预读:锁章末尾时提前挂载其后 N 章</div> label="预读:锁章末尾时提前挂载其后 N 章"
<input ariaLabel="预读章数"
type="range" min={0}
min={0} max={3}
max={3} value={prefetch}
step={1} onChange={setPrefetch}
value={prefetch} />
aria-label="预读章数"
className="rd-range"
onChange={(e) => setPrefetch(Number(e.target.value))}
/>
<div className="flex justify-between px-1 text-[10px] tabular-nums opacity-50" aria-hidden="true">
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</div>
)} )}
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Portal> </DropdownMenu.Portal>