mirror of
https://github.com/hex248/tsos.git
synced 2026-02-07 18:23:05 +00:00
sidebar controls (shape selection and roundness slider)
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import ShapeCanvas from "@/components/canvas/ShapeCanvas";
|
import ShapeCanvas from "@/components/canvas/ShapeCanvas";
|
||||||
|
import PresetSelector from "@/components/controls/PresetSelector";
|
||||||
|
import { Slider } from "@/components/ui/slider";
|
||||||
import { useShapeState } from "@/hooks/useShapeState";
|
import { useShapeState } from "@/hooks/useShapeState";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import Layout from "./Layout";
|
import Layout from "./Layout";
|
||||||
|
import { cn } from "./lib/utils";
|
||||||
|
|
||||||
function Index() {
|
function Index() {
|
||||||
const [dimensions, setDimensions] = useState({
|
const [dimensions, setDimensions] = useState({
|
||||||
@@ -26,8 +29,34 @@ function Index() {
|
|||||||
|
|
||||||
const [state, setState] = useShapeState(centerX, centerY);
|
const [state, setState] = useShapeState(centerX, centerY);
|
||||||
|
|
||||||
|
const sidebarContent = (
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<span className="text-sm font-medium">Shape</span>
|
||||||
|
<PresetSelector value={state.preset} onChange={(preset) => setState({ ...state, preset })} />
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"text-sm font-medium",
|
||||||
|
state.preset === "circle" ? "opacity-50 pointer-events-none select-none" : "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Roundness
|
||||||
|
</span>
|
||||||
|
<Slider
|
||||||
|
value={[state.roundness]}
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
onValueChange={([v]) => setState({ ...state, roundness: v })}
|
||||||
|
className={state.preset === "circle" ? "opacity-50 pointer-events-none" : ""}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout sidebarContent={<>controls here</>}>
|
<Layout sidebarContent={sidebarContent}>
|
||||||
<ShapeCanvas state={state} onStateChange={setState} />
|
<ShapeCanvas state={state} onStateChange={setState} />
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|||||||
31
src/components/controls/PresetSelector.tsx
Normal file
31
src/components/controls/PresetSelector.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import type { Preset } from "@/types/shape";
|
||||||
|
|
||||||
|
const presets: { value: Preset; label: string }[] = [
|
||||||
|
{ value: "triangle", label: "Triangle" },
|
||||||
|
{ value: "square", label: "Square" },
|
||||||
|
{ value: "circle", label: "Circle" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function PresetSelector({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
value: Preset;
|
||||||
|
onChange: (preset: Preset) => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="flex gap-2">
|
||||||
|
{presets.map((preset) => (
|
||||||
|
<Button
|
||||||
|
key={preset.value}
|
||||||
|
variant={value === preset.value ? "default" : "outline"}
|
||||||
|
size="sm"
|
||||||
|
onClick={() => onChange(preset.value)}
|
||||||
|
>
|
||||||
|
{preset.label}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ const buttonVariants = cva(
|
|||||||
{
|
{
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
default: "bg-primary text-primary-foreground hover:bg-primary/90 border border-primary",
|
||||||
destructive:
|
destructive:
|
||||||
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||||
outline:
|
outline:
|
||||||
|
|||||||
Reference in New Issue
Block a user