feat(editor): add FontSizeSlider component for font size control in code editor

This commit is contained in:
ngc2207 2024-12-31 23:59:32 +08:00
parent 0be9cf3baa
commit bc39266f2c
3 changed files with 78 additions and 0 deletions

View File

@ -15,6 +15,7 @@
"@radix-ui/react-avatar": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.4",
"@radix-ui/react-select": "^2.1.4",
"@radix-ui/react-slider": "^1.2.2",
"@radix-ui/react-slot": "^1.1.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",

View 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>
);
}

View 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 }