remove line and peykan from sidebar and added to shape

This commit is contained in:
hamid zarghami
2026-06-13 16:26:52 +03:30
parent f9113ef9c8
commit 46f5389036
3 changed files with 53 additions and 18 deletions
@@ -7,8 +7,6 @@ import {
SelectInstruction, SelectInstruction,
RectangleInstruction, RectangleInstruction,
TextInstruction, TextInstruction,
LineInstruction,
ArrowInstruction,
StickerInstruction, StickerInstruction,
GridInstruction, GridInstruction,
CustomShapeInstruction, CustomShapeInstruction,
@@ -38,9 +36,9 @@ const ToolInstructions = ({ tool }: ToolInstructionsProps) => {
const simpleInstructions: Partial<Record<ToolType, React.ReactElement>> = { const simpleInstructions: Partial<Record<ToolType, React.ReactElement>> = {
select: <SelectInstruction />, select: <SelectInstruction />,
rectangle: <RectangleInstruction />, rectangle: <RectangleInstruction />,
line: <RectangleInstruction />,
arrow: <RectangleInstruction />,
text: <TextInstruction />, text: <TextInstruction />,
line: <LineInstruction />,
arrow: <ArrowInstruction />,
sticker: <StickerInstruction />, sticker: <StickerInstruction />,
grid: <GridInstruction />, grid: <GridInstruction />,
"custom-shape": <CustomShapeInstruction />, "custom-shape": <CustomShapeInstruction />,
@@ -1,6 +1,5 @@
import { clx } from "@/helpers/utils"; import { clx } from "@/helpers/utils";
import { import {
ArrowLeft,
Gallery, Gallery,
Grid8, Grid8,
MouseSquare, MouseSquare,
@@ -9,7 +8,6 @@ import {
Text, Text,
VideoSquare, VideoSquare,
Music, Music,
Minus,
Link2, Link2,
Magicpen, Magicpen,
} from "iconsax-react"; } from "iconsax-react";
@@ -17,15 +15,13 @@ import type { ToolType } from "../../store/editorStore";
const tools: Array<{ icon: (color: string, variant?: "Bold" | "Outline" | "Broken" | "Bulk" | "Linear" | "TwoTone") => React.ReactNode; tool: ToolType; label: string }> = [ const tools: Array<{ icon: (color: string, variant?: "Bold" | "Outline" | "Broken" | "Bulk" | "Linear" | "TwoTone") => React.ReactNode; tool: ToolType; label: string }> = [
{ icon: (color, variant) => <MouseSquare size={20} color={color} variant={variant} />, tool: "select", label: "انتخاب" }, { icon: (color, variant) => <MouseSquare size={20} color={color} variant={variant} />, tool: "select", label: "انتخاب" },
{ icon: (color, variant) => <Shapes size={20} color={color} variant={variant} />, tool: "rectangle", label: "مستطیل" }, { icon: (color, variant) => <Shapes size={20} color={color} variant={variant} />, tool: "rectangle", label: "اشکال" },
{ icon: (color, variant) => <Text size={20} color={color} variant={variant} />, tool: "text", label: "متن" }, { icon: (color, variant) => <Text size={20} color={color} variant={variant} />, tool: "text", label: "متن" },
{ icon: (color, variant) => <Grid8 size={20} color={color} variant={variant} />, tool: "grid", label: "گرید" }, { icon: (color, variant) => <Grid8 size={20} color={color} variant={variant} />, tool: "grid", label: "گرید" },
{ icon: (color, variant) => <Gallery size={20} color={color} variant={variant} />, tool: "image", label: "گالری" }, { icon: (color, variant) => <Gallery size={20} color={color} variant={variant} />, tool: "image", label: "گالری" },
{ icon: (color, variant) => <Link2 size={20} color={color} variant={variant} />, tool: "link", label: "لینک" }, { icon: (color, variant) => <Link2 size={20} color={color} variant={variant} />, tool: "link", label: "لینک" },
{ icon: (color, variant) => <VideoSquare size={20} color={color} variant={variant} />, tool: "video", label: "ویدیو" }, { icon: (color, variant) => <VideoSquare size={20} color={color} variant={variant} />, tool: "video", label: "ویدیو" },
{ icon: (color, variant) => <Music size={20} color={color} variant={variant} />, tool: "audio", label: "صدا" }, { icon: (color, variant) => <Music size={20} color={color} variant={variant} />, tool: "audio", label: "صدا" },
{ icon: (color, variant) => <ArrowLeft size={20} color={color} variant={variant} />, tool: "arrow", label: "پیکان" },
{ icon: (color, variant) => <Minus size={20} color={color} variant={variant} />, tool: "line", label: "خط" },
{ icon: (color, variant) => <Sticker size={20} color={color} variant={variant} />, tool: "sticker", label: "استیکر" }, { icon: (color, variant) => <Sticker size={20} color={color} variant={variant} />, tool: "sticker", label: "استیکر" },
{ icon: (color, variant) => <Magicpen size={20} color={color} variant={variant} />, tool: "custom-shape", label: "شکل سفارشی" }, { icon: (color, variant) => <Magicpen size={20} color={color} variant={variant} />, tool: "custom-shape", label: "شکل سفارشی" },
]; ];
@@ -39,7 +35,10 @@ const ToolsBar = ({ tool, onToolClick }: ToolsBarProps) => {
return ( return (
<div className="flex h-full max-w-[72px] flex-1 flex-col items-center gap-4 overflow-y-auto border-l border-border py-2"> <div className="flex h-full max-w-[72px] flex-1 flex-col items-center gap-4 overflow-y-auto border-l border-border py-2">
{tools.map((item, index) => { {tools.map((item, index) => {
const isActive = tool === item.tool; const isActive =
item.tool === "rectangle"
? tool === "rectangle" || tool === "line" || tool === "arrow"
: tool === item.tool;
const iconColor = "black"; const iconColor = "black";
const iconVariant: "Bold" | "Outline" | "Broken" | "Bulk" | "Linear" | "TwoTone" | undefined = isActive ? "Bold" : "Outline"; const iconVariant: "Bold" | "Outline" | "Broken" | "Bulk" | "Linear" | "TwoTone" | undefined = isActive ? "Bold" : "Outline";
return ( return (
@@ -1,10 +1,12 @@
import { type FC } from "react"; import { type FC } from "react";
import { ArrowLeft, Minus } from "iconsax-react";
import SquareIcon from "@/assets/icons/square.svg"; import SquareIcon from "@/assets/icons/square.svg";
import CircleIcon from "@/assets/icons/circle.svg"; import CircleIcon from "@/assets/icons/circle.svg";
import TriangleIcon from "@/assets/icons/triangle.svg"; import TriangleIcon from "@/assets/icons/triangle.svg";
import StarIcon from "@/assets/icons/Star.svg"; import StarIcon from "@/assets/icons/Star.svg";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { clx } from "@/helpers/utils"; import { clx } from "@/helpers/utils";
import { useEditorStore } from "@/pages/editor/store/editorStore";
import { useShapeStore, type ShapeType } from "@/pages/editor/store/shapeStore"; import { useShapeStore, type ShapeType } from "@/pages/editor/store/shapeStore";
const shapeOptions: Array<{ id: ShapeType; label: string; icon: string; alt: string }> = [ const shapeOptions: Array<{ id: ShapeType; label: string; icon: string; alt: string }> = [
@@ -14,21 +16,33 @@ const shapeOptions: Array<{ id: ShapeType; label: string; icon: string; alt: str
{ id: "abstract", label: "انتزاعی", icon: StarIcon, alt: "abstract" }, { id: "abstract", label: "انتزاعی", icon: StarIcon, alt: "abstract" },
]; ];
const drawOptions = [
{ tool: "line" as const, label: "خط", Icon: Minus },
{ tool: "arrow" as const, label: "پیکان", Icon: ArrowLeft },
];
const RectangleInstruction: FC = () => { const RectangleInstruction: FC = () => {
const tool = useEditorStore((state) => state.tool);
const setTool = useEditorStore((state) => state.setTool);
const { activeShape, setActiveShape, useAsMask, setUseAsMask } = useShapeStore(); const { activeShape, setActiveShape, useAsMask, setUseAsMask } = useShapeStore();
const handleShapeClick = (shapeId: ShapeType) => {
setActiveShape(shapeId);
setTool("rectangle");
};
return ( return (
<div> <div>
<h2 className="font-bold">اشکال</h2> <h2 className="font-bold">اشکال</h2>
<div className="mt-7 flex flex-wrap gap-3 text-[#B2B2B2]"> <div className="mt-7 flex flex-wrap gap-3 text-[#B2B2B2]">
{shapeOptions.map((shape) => { {shapeOptions.map((shape) => {
const isActive = activeShape === shape.id; const isActive = tool === "rectangle" && activeShape === shape.id;
return ( return (
<button <button
type="button" type="button"
key={shape.id} key={shape.id}
onClick={() => setActiveShape(shape.id)} onClick={() => handleShapeClick(shape.id)}
className={clx( className={clx(
"size-[60px] flex flex-col gap-1 justify-center items-center rounded-xl text-[13px] transition-colors", "size-[60px] flex flex-col gap-1 justify-center items-center rounded-xl text-[13px] transition-colors",
isActive ? "" : "border-transparent", isActive ? "" : "border-transparent",
@@ -40,16 +54,40 @@ const RectangleInstruction: FC = () => {
</button> </button>
); );
})} })}
{drawOptions.map(({ tool: drawTool, label, Icon }) => {
const isActive = tool === drawTool;
return (
<button
type="button"
key={drawTool}
onClick={() => setTool(drawTool)}
className={clx(
"size-[60px] flex flex-col gap-1 justify-center items-center rounded-xl text-[13px] transition-colors",
isActive ? "" : "border-transparent",
)}
aria-pressed={isActive}
>
<Icon size={24} color={isActive ? "black" : "#7A7A7A"} variant={isActive ? "Bold" : "Outline"} />
<div className={clx(isActive ? "text-black" : "text-[#7A7A7A]")}>{label}</div>
</button>
);
})}
</div> </div>
<div className="mt-9 flex items-center justify-between"> {tool === "rectangle" && (
<div className="text-[13px]">استفاده برای ماسک</div> <div className="mt-9 flex items-center justify-between">
<Switch checked={useAsMask} onCheckedChange={setUseAsMask} /> <div className="text-[13px]">استفاده برای ماسک</div>
</div> <Switch checked={useAsMask} onCheckedChange={setUseAsMask} />
</div>
)}
{(tool === "line" || tool === "arrow") && (
<p className="mt-9 text-sm text-gray-600">
{tool === "line" ? "برای رسم خط، روی کانوس کلیک کرده و بکشید" : "برای رسم پیکان، روی کانوس کلیک کرده و بکشید"}
</p>
)}
</div> </div>
); );
}; };
export default RectangleInstruction; export default RectangleInstruction;