mirror of
https://litchi.icu/ngc2207/judge.git
synced 2025-05-18 22:46:45 +00:00
feat(editor): add FontSizeSlider component for font size control in code editor
This commit is contained in:
parent
0be9cf3baa
commit
bc39266f2c
@ -15,6 +15,7 @@
|
|||||||
"@radix-ui/react-avatar": "^1.1.2",
|
"@radix-ui/react-avatar": "^1.1.2",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
||||||
"@radix-ui/react-select": "^2.1.4",
|
"@radix-ui/react-select": "^2.1.4",
|
||||||
|
"@radix-ui/react-slider": "^1.2.2",
|
||||||
"@radix-ui/react-slot": "^1.1.1",
|
"@radix-ui/react-slot": "^1.1.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
49
src/app/(main)/components/font-size-slider.tsx
Normal file
49
src/app/(main)/components/font-size-slider.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Slider } from "@/components/ui/slider";
|
||||||
|
import { useCodeEditorStore } from "@/store/useCodeEditorStore";
|
||||||
|
import { MAX_FONT_SIZE, MIN_FONT_SIZE } from "@/constants/editor/options";
|
||||||
|
|
||||||
|
export default function FontSizeSlider() {
|
||||||
|
const skipInterval = 2;
|
||||||
|
const ticks = [...Array(MAX_FONT_SIZE - MIN_FONT_SIZE + 1)].map(
|
||||||
|
(_, i) => i + MIN_FONT_SIZE
|
||||||
|
);
|
||||||
|
const { fontSize, setFontSize } = useCodeEditorStore();
|
||||||
|
|
||||||
|
const handleSliderChange = (value: number[]) => {
|
||||||
|
setFontSize(value[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-48 h-8">
|
||||||
|
<Slider
|
||||||
|
value={[fontSize]}
|
||||||
|
min={MIN_FONT_SIZE}
|
||||||
|
max={MAX_FONT_SIZE}
|
||||||
|
onValueChange={handleSliderChange}
|
||||||
|
aria-label="Slider with ticks"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="mt-3 flex w-full items-center justify-between gap-1 px-2.5 text-xs font-medium text-muted-foreground"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
{ticks.map((tick, i) => (
|
||||||
|
<span
|
||||||
|
key={i}
|
||||||
|
className="flex w-0 flex-col items-center justify-center gap-2"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"h-1 w-px bg-muted-foreground/70",
|
||||||
|
i % skipInterval !== 0 && "h-0.5"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<span className={cn(i % skipInterval !== 0 && "opacity-0")}>
|
||||||
|
{tick}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
28
src/components/ui/slider.tsx
Normal file
28
src/components/ui/slider.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as SliderPrimitive from "@radix-ui/react-slider"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Slider = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SliderPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SliderPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex w-full touch-none select-none items-center",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20">
|
||||||
|
<SliderPrimitive.Range className="absolute h-full bg-primary" />
|
||||||
|
</SliderPrimitive.Track>
|
||||||
|
<SliderPrimitive.Thumb className="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
|
||||||
|
</SliderPrimitive.Root>
|
||||||
|
))
|
||||||
|
Slider.displayName = SliderPrimitive.Root.displayName
|
||||||
|
|
||||||
|
export { Slider }
|
Loading…
Reference in New Issue
Block a user