seat-editor 1.2.25 → 1.2.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/{layout.js → layout.jsx} +7 -4
- package/dist/app/new-board/page.jsx +12 -0
- package/dist/app/old-board/{page.js → page.jsx} +214 -148
- package/dist/app/only-view/{page.js → page.jsx} +14 -11
- package/dist/app/page.jsx +13 -0
- package/dist/components/button-tools/index.jsx +17 -0
- package/dist/components/form-tools/label.jsx +44 -0
- package/dist/components/form-tools/shape.jsx +43 -0
- package/dist/components/input/{number-indicator.js → number-indicator.jsx} +11 -7
- package/dist/components/layer/index.jsx +254 -0
- package/dist/components/lib/{index.js → index.jsx} +7 -5
- package/dist/components/modal-preview/index.jsx +11 -0
- package/dist/features/board/{index.js → index.jsx} +37 -30
- package/dist/features/navbar/{index.js → index.jsx} +1 -1
- package/dist/features/package/{index.js → index.jsx} +7 -5
- package/dist/features/panel/{index.js → index.jsx} +15 -11
- package/dist/features/panel/{select-tool.js → select-tool.jsx} +16 -15
- package/dist/features/panel/{square-circle-tool.js → square-circle-tool.jsx} +4 -3
- package/dist/features/panel/table-seat-circle.jsx +31 -0
- package/dist/features/panel/text-tool.jsx +22 -0
- package/dist/features/panel/{upload-tool.js → upload-tool.jsx} +16 -8
- package/dist/features/side-tool/{index.js → index.jsx} +59 -55
- package/dist/features/view/{index.js → index.jsx} +30 -26
- package/dist/provider/antd-provider.jsx +30 -0
- package/dist/provider/{redux-provider.js → redux-provider.jsx} +1 -1
- package/dist/provider/{store-provider.js → store-provider.jsx} +3 -2
- package/package.json +1 -1
- package/dist/app/new-board/page.js +0 -10
- package/dist/app/page.js +0 -11
- package/dist/components/button-tools/index.js +0 -14
- package/dist/components/form-tools/label.js +0 -26
- package/dist/components/form-tools/shape.js +0 -29
- package/dist/components/layer/index.js +0 -192
- package/dist/components/modal-preview/index.js +0 -10
- package/dist/features/panel/table-seat-circle.js +0 -22
- package/dist/features/panel/text-tool.js +0 -16
- package/dist/provider/antd-provider.js +0 -27
|
@@ -17,8 +17,11 @@ export const metadata = {
|
|
|
17
17
|
description: "Generated by create next app",
|
|
18
18
|
};
|
|
19
19
|
export default function RootLayout({ children, }) {
|
|
20
|
-
return (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
return (<html lang="en">
|
|
21
|
+
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
|
|
22
|
+
<StoreProvider>
|
|
23
|
+
<Layout>{children}</Layout>
|
|
24
|
+
</StoreProvider>
|
|
25
|
+
</body>
|
|
26
|
+
</html>);
|
|
24
27
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Board from "../../features/board";
|
|
2
|
+
import SideTool from "../../features/side-tool";
|
|
3
|
+
import ControlPanels from "../../features/panel";
|
|
4
|
+
export default function NewBoard() {
|
|
5
|
+
return (<>
|
|
6
|
+
<div className="w-full h-screen flex relative">
|
|
7
|
+
<SideTool />
|
|
8
|
+
<Board />
|
|
9
|
+
<ControlPanels />
|
|
10
|
+
</div>
|
|
11
|
+
</>);
|
|
12
|
+
}
|
|
@@ -297,153 +297,219 @@ const SeatEditor = () => {
|
|
|
297
297
|
// link.click();
|
|
298
298
|
// document.body.removeChild(link);
|
|
299
299
|
};
|
|
300
|
-
return (
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
300
|
+
return (<div className="flex h-screen w-full">
|
|
301
|
+
{/* Toolbar */}
|
|
302
|
+
<div className="w-16 bg-gray-800 text-white flex flex-col items-center py-4 space-y-4">
|
|
303
|
+
{/* Select Tool */}
|
|
304
|
+
<Button type={activeTool === "select" ? "primary" : "default"} shape="circle" icon={<MousePointer2 />} onClick={() => handleToolClick("select")}/>
|
|
305
|
+
<Button type={activeTool === "circle" ? "primary" : "default"} shape="circle" icon={<Circle />} onClick={() => handleToolClick("circle")}/>
|
|
306
|
+
<Button type={activeTool === "vip-seat" ? "primary" : "default"} shape="circle" icon={<PenIcon />} // Use any icon you prefer
|
|
307
|
+
onClick={() => handleToolClick("vip-seat")}/>
|
|
308
|
+
{/* Rectangle Tool */}
|
|
309
|
+
<Button type={activeTool === "rectangle" ? "primary" : "default"} shape="circle" icon={<Square />} onClick={() => handleToolClick("rectangle")}/>
|
|
310
|
+
{/* Node Tool */}
|
|
311
|
+
<Button type={activeTool === "node" ? "primary" : "default"} shape="circle" icon={<Move3D />} onClick={() => handleToolClick("node")}/>
|
|
312
|
+
<Button type={activeTool === "pen" ? "primary" : "default"} shape="circle" icon={<Pencil />} onClick={() => handleToolClick("pen")}/>
|
|
313
|
+
|
|
314
|
+
{/* delete */}
|
|
315
|
+
<Button type="default" shape="circle" icon={<Trash />} onClick={deleteSelectedRectangle}/>
|
|
316
|
+
{/* duplicate */}
|
|
317
|
+
<Button type="default" shape="circle" icon={<CopyPlusIcon />} // You can use a copy icon
|
|
318
|
+
onClick={duplicateRectangle}/>
|
|
319
|
+
{/* zoomIn/out */}
|
|
320
|
+
<Button type="default" shape="circle" onClick={zoomIn} icon={<ZoomInIcon />}/>
|
|
321
|
+
<Button type="default" shape="circle" onClick={zoomOut} icon={<ZoomOutIcon />}/>
|
|
322
|
+
{/* {activeTool === "image" && ( */}
|
|
323
|
+
<UploadIcon />
|
|
324
|
+
<span>Image Seat</span>
|
|
325
|
+
<input type="file" accept="image/*" onChange={handleImageUpload}/>
|
|
326
|
+
<span>Background Image</span>
|
|
327
|
+
<input type="file" accept="image/*" onChange={handleImageUploadBackground}/>
|
|
328
|
+
{/* )} */}
|
|
329
|
+
<Button shape="circle" icon={<DownloadIcon />} onClick={exportJSON}/>
|
|
330
|
+
</div>
|
|
331
|
+
|
|
332
|
+
{/* Workspace */}
|
|
333
|
+
<div className="w-full flex items-center justify-center" id={"workspace"}>
|
|
334
|
+
<div className={`bg-gray-900 relative ${getCursorStyle()} w-full h-screen `} onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} style={{
|
|
335
|
+
transform: `scale(${zoom})`,
|
|
336
|
+
transformOrigin: "0 0",
|
|
337
|
+
}}>
|
|
338
|
+
|
|
339
|
+
{shadowRect && (<div className="absolute border-dashed border-2 border-blue-400" style={{
|
|
340
|
+
left: shadowRect.x,
|
|
341
|
+
top: shadowRect.y,
|
|
342
|
+
width: shadowRect.width,
|
|
343
|
+
height: shadowRect.height,
|
|
344
|
+
backgroundColor: shadowRect.color,
|
|
345
|
+
}}/>)}
|
|
346
|
+
{/* Render rectangles */}
|
|
347
|
+
{rectangles.map((rect) => (<div key={rect.id} onMouseDown={(e) => handleRectangleMouseDown(e, rect)} onDoubleClick={() => handleRectangleDoubleClick(rect)} className={`absolute cursor-move border transition-transform ${(selectedRectangle === null || selectedRectangle === void 0 ? void 0 : selectedRectangle.id) === rect.id
|
|
348
|
+
? "border-black"
|
|
349
|
+
: "border-gray-300"}`} style={{
|
|
350
|
+
left: rect.x,
|
|
351
|
+
top: rect.y,
|
|
352
|
+
width: rect.width,
|
|
353
|
+
height: rect.height,
|
|
354
|
+
backgroundColor: rect.color,
|
|
355
|
+
transform: `rotate(${rect.rotation}deg)`,
|
|
356
|
+
transformOrigin: "center",
|
|
357
|
+
borderRadius: rect.shape === "circle" ? "100%" : "0%",
|
|
358
|
+
}}>
|
|
359
|
+
{rect.shape === "image-table" && (<div className="w-full h-full relative">
|
|
360
|
+
<img src={rect.src} alt="custom" className="w-full h-full object-cover" draggable={false}/>
|
|
361
|
+
<div className="absolute left-0 right-0 flex items-center justify-center" style={{
|
|
362
|
+
top: "10%",
|
|
363
|
+
height: "20%",
|
|
364
|
+
backgroundColor: rect.highlightColor || "transparent",
|
|
365
|
+
}}>
|
|
366
|
+
<span className="text-white font-bold text-xs absolute" style={{
|
|
367
|
+
top: "10%",
|
|
368
|
+
left: "50%",
|
|
369
|
+
}}>
|
|
370
|
+
{rect.table}
|
|
371
|
+
</span>
|
|
372
|
+
</div>
|
|
373
|
+
<span className="text-xs text-white flex items-center justify-center absolute w-full" style={{
|
|
374
|
+
top: "85%",
|
|
375
|
+
left: "50%",
|
|
376
|
+
transform: "translate(-50%, -50%)",
|
|
377
|
+
backgroundColor: rect.highlightColor || "transparent"
|
|
378
|
+
}}>
|
|
379
|
+
{rect.pax}
|
|
380
|
+
</span>
|
|
381
|
+
<div className="absolute left-0 right-0 flex items-center justify-center" style={{
|
|
382
|
+
top: "40%",
|
|
383
|
+
height: "20%",
|
|
384
|
+
backgroundColor: rect.highlightColor || "transparent",
|
|
385
|
+
}}>
|
|
386
|
+
<span className="text-white font-bold text-xs">
|
|
387
|
+
{rect.status}
|
|
388
|
+
</span>
|
|
389
|
+
</div>
|
|
390
|
+
</div>)}
|
|
391
|
+
{rect.shape === "image" && (<img src={rect.src} alt="custom" className="w-full h-full object-cover" draggable={false}/>)}
|
|
392
|
+
{rect.shape === "vip-seat" && (<div className="absolute left-0 right-0 flex items-center justify-center" style={{
|
|
393
|
+
top: "10%",
|
|
394
|
+
height: "20%",
|
|
395
|
+
}}>
|
|
396
|
+
<span className="text-white font-bold text-xs">
|
|
397
|
+
{rect.table}
|
|
398
|
+
</span>
|
|
399
|
+
</div>)}
|
|
400
|
+
{rect.shape === "vip-seat" && (<div className="absolute left-0 right-0 flex items-center justify-center" style={{
|
|
401
|
+
top: "40%",
|
|
402
|
+
height: "20%",
|
|
403
|
+
backgroundColor: rect.highlightColor || "transparent",
|
|
404
|
+
}}>
|
|
405
|
+
<span className="text-white font-bold text-xs">
|
|
406
|
+
{rect.status}
|
|
407
|
+
</span>
|
|
408
|
+
</div>)}
|
|
409
|
+
|
|
410
|
+
{/* Bottom Text */}
|
|
411
|
+
<div className="absolute bottom-2 left-0 right-0 text-center text-white text-sm">
|
|
412
|
+
{rect.shape === "vip-seat" ? "8 Pax" : ""}
|
|
413
|
+
</div>
|
|
414
|
+
|
|
415
|
+
{/* Resize Nodes */}
|
|
416
|
+
{/* Resize Nodes (Only Show When in Node Mode and Item is Selected) */}
|
|
417
|
+
{activeTool === "node" && (selectedRectangle === null || selectedRectangle === void 0 ? void 0 : selectedRectangle.id) === rect.id && (<>
|
|
418
|
+
{/* Top Left */}
|
|
419
|
+
<div className="absolute w-3 h-3 bg-white border border-gray-800" style={{
|
|
420
|
+
top: -6,
|
|
421
|
+
left: -6,
|
|
422
|
+
cursor: "nwse-resize",
|
|
423
|
+
borderRadius: rect.shape === "circle" ? "50%" : "0%",
|
|
424
|
+
}} onMouseDown={() => startResizing("top-left")}/>
|
|
425
|
+
{/* Top Right */}
|
|
426
|
+
<div className="absolute w-3 h-3 bg-white border border-gray-800" style={{
|
|
427
|
+
top: -6,
|
|
428
|
+
right: -6,
|
|
429
|
+
cursor: "nesw-resize",
|
|
430
|
+
borderRadius: rect.shape === "circle" ? "50%" : "0%",
|
|
431
|
+
}} onMouseDown={() => startResizing("top-right")}/>
|
|
432
|
+
{/* Bottom Left */}
|
|
433
|
+
<div className="absolute w-3 h-3 bg-white border border-gray-800" style={{
|
|
434
|
+
bottom: -6,
|
|
435
|
+
left: -6,
|
|
436
|
+
cursor: "nesw-resize",
|
|
437
|
+
borderRadius: rect.shape === "circle" ? "50%" : "0%",
|
|
438
|
+
}} onMouseDown={() => startResizing("bottom-left")}/>
|
|
439
|
+
{/* Bottom Right */}
|
|
440
|
+
<div className="absolute w-3 h-3 bg-white border border-gray-800" style={{
|
|
441
|
+
bottom: -6,
|
|
442
|
+
right: -6,
|
|
443
|
+
cursor: "nwse-resize",
|
|
444
|
+
borderRadius: rect.shape === "circle" ? "50%" : "0%",
|
|
445
|
+
}} onMouseDown={() => startResizing("bottom-right")}/>
|
|
446
|
+
</>)}
|
|
447
|
+
</div>))}
|
|
448
|
+
</div>
|
|
449
|
+
</div>
|
|
450
|
+
|
|
451
|
+
{/* Rectangle Customization Modal */}
|
|
452
|
+
<Modal open={showModal} onCancel={() => setShowModal(false)} onOk={() => setShowModal(false)} title="Edit Rectangle">
|
|
453
|
+
{selectedRectangle && (<>
|
|
454
|
+
<div className="flex gap-4 items-center">
|
|
455
|
+
<div className="flex flex-col">
|
|
456
|
+
<p className="mb-2 font-semibold">Change Color:</p>
|
|
457
|
+
<SketchPicker color={selectedRectangle.color} onChangeComplete={(color) => updateRectangle({ color: color.hex })}/>
|
|
458
|
+
</div>
|
|
459
|
+
<div className="flex flex-col">
|
|
460
|
+
<p className="mt-4 mb-2 font-semibold">Live Preview:</p>
|
|
461
|
+
<div className="relative borderflex items-center justify-center" style={{
|
|
462
|
+
width: selectedRectangle.width,
|
|
463
|
+
height: selectedRectangle.height,
|
|
464
|
+
margin: "0 auto",
|
|
465
|
+
transform: `rotate(${selectedRectangle.rotation}deg)`,
|
|
466
|
+
backgroundColor: selectedRectangle.color,
|
|
467
|
+
transition: "all 0.3s ease",
|
|
468
|
+
scale: "0.5",
|
|
469
|
+
borderRadius: selectedRectangle.shape === "circle" ? "100%" : "0%",
|
|
470
|
+
}}>
|
|
471
|
+
{selectedRectangle.shape === "vip-seat" && (<div className="absolute left-0 right-0 flex items-center justify-center" style={{
|
|
472
|
+
top: "10%",
|
|
473
|
+
height: "20%",
|
|
474
|
+
}}>
|
|
475
|
+
<span className="text-white font-bold text-xs">
|
|
476
|
+
{selectedRectangle.status}sfsdf
|
|
477
|
+
</span>
|
|
478
|
+
</div>)}
|
|
479
|
+
{selectedRectangle.shape === "vip-seat" && (<div className="absolute left-0 right-0 flex items-center justify-center" style={{
|
|
480
|
+
top: "40%",
|
|
481
|
+
height: "20%",
|
|
482
|
+
backgroundColor: selectedRectangle.highlightColor || "transparent",
|
|
483
|
+
}}>
|
|
484
|
+
<span className="text-white font-bold text-xs">
|
|
485
|
+
{selectedRectangle.status} dsdsd
|
|
486
|
+
</span>
|
|
487
|
+
</div>)}
|
|
488
|
+
</div>
|
|
489
|
+
</div>
|
|
490
|
+
</div>
|
|
491
|
+
|
|
492
|
+
{/* Preview Section */}
|
|
493
|
+
|
|
494
|
+
<p className="mt-4 mb-2 font-semibold">Edit Text:</p>
|
|
495
|
+
<Input value={selectedRectangle.pax} onChange={(e) => updateRectangle({ pax: e.target.value })}/>
|
|
496
|
+
<p className="mt-4 mb-2 font-semibold">Edit Label:</p>
|
|
497
|
+
<Input value={selectedRectangle.table} onChange={(e) => updateRectangle({ table: e.target.value })}/>
|
|
498
|
+
<p className="mt-4 mb-2 font-semibold">Edit Highlight:</p>
|
|
499
|
+
<Input value={selectedRectangle.status} onChange={(e) => updateRectangle({ status: e.target.value })}/>
|
|
500
|
+
{/* Rotation Controls */}
|
|
501
|
+
<p className="mt-4 mb-2 font-semibold">Rotate:</p>
|
|
502
|
+
<div className="flex gap-4 items-center">
|
|
503
|
+
<Button onClick={() => rotateRectangle("left")}>
|
|
504
|
+
⟲ Rotate Left
|
|
505
|
+
</Button>
|
|
506
|
+
<span>{selectedRectangle.rotation}°</span>
|
|
507
|
+
<Button onClick={() => rotateRectangle("right")}>
|
|
508
|
+
⟳ Rotate Right
|
|
509
|
+
</Button>
|
|
510
|
+
</div>
|
|
511
|
+
</>)}
|
|
512
|
+
</Modal>
|
|
513
|
+
</div>);
|
|
448
514
|
};
|
|
449
515
|
export default SeatEditor;
|
|
@@ -34,16 +34,19 @@ const TouchScrollDetect = () => {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
}, []);
|
|
37
|
-
return (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
return (<div id="scroll-container" className="h-screen overflow-y-scroll bg-gray-100 p-6 text-gray-800">
|
|
38
|
+
<LayerView statusKey="status" defaultBackground="#000000"/>
|
|
39
|
+
<div className="sticky top-0 bg-white z-10 py-2">
|
|
40
|
+
{scrollType === "one" && (<p className="text-blue-600 font-medium">👆 One-finger scroll</p>)}
|
|
41
|
+
{scrollType === "two" && (<p className="text-green-600 font-medium">✌️ Two-finger scroll</p>)}
|
|
42
|
+
{scrollType === "other" && (<p className="text-red-600 font-medium">
|
|
43
|
+
🖐️ {fingerCount} fingers on screen
|
|
44
|
+
</p>)}
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div className="h-[2000px] bg-white mt-4 rounded p-4 shadow">
|
|
48
|
+
<p>Scroll this page with 1 or 2 fingers.</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>);
|
|
48
51
|
};
|
|
49
52
|
export default TouchScrollDetect;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Board from "../features/board";
|
|
2
|
+
import SideTool from "../features/side-tool";
|
|
3
|
+
import ControlPanels from "../features/panel";
|
|
4
|
+
const TableEditor = () => {
|
|
5
|
+
return (<>
|
|
6
|
+
<div className="w-full h-screen flex relative">
|
|
7
|
+
<SideTool />
|
|
8
|
+
<Board />
|
|
9
|
+
<ControlPanels />
|
|
10
|
+
</div>
|
|
11
|
+
</>);
|
|
12
|
+
};
|
|
13
|
+
export default TableEditor;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button, Popover } from "antd";
|
|
3
|
+
const ButtonTools = (props) => {
|
|
4
|
+
const { buttonProps, items, popoverProps } = props;
|
|
5
|
+
if (items.length === 0) {
|
|
6
|
+
return (<Popover trigger="hover" {...popoverProps}>
|
|
7
|
+
<Button {...buttonProps}/>
|
|
8
|
+
</Popover>);
|
|
9
|
+
}
|
|
10
|
+
return (<Popover content={<div>
|
|
11
|
+
<Button>Button 1</Button>
|
|
12
|
+
<Button>Button 2</Button>
|
|
13
|
+
</div>} trigger="click">
|
|
14
|
+
<Button {...buttonProps}/>
|
|
15
|
+
</Popover>);
|
|
16
|
+
};
|
|
17
|
+
export default ButtonTools;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button, ColorPicker, Flex, Form, Input, InputNumber } from "antd";
|
|
3
|
+
const SectionLabel = () => {
|
|
4
|
+
return (<div className="py-2">
|
|
5
|
+
<h1 className="heading-s">Section Labeling</h1>
|
|
6
|
+
<Form.Item label="Labels in square" name={"labels"}>
|
|
7
|
+
<Form.List name="labels">
|
|
8
|
+
{(fields, { add, remove }) => (<>
|
|
9
|
+
{fields.map((field) => (<div key={field.key}>
|
|
10
|
+
<Flex gap={2}>
|
|
11
|
+
<Form.Item name={[field.name, "label"]} label="Text">
|
|
12
|
+
<Input />
|
|
13
|
+
</Form.Item>
|
|
14
|
+
<Form.Item name={[field.name, "fontColor"]} label="Color" getValueFromEvent={(color) => color.toHexString()}>
|
|
15
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
16
|
+
</Form.Item>
|
|
17
|
+
</Flex>
|
|
18
|
+
<Flex gap={2}>
|
|
19
|
+
<Form.Item name={[field.name, "x"]} label="X">
|
|
20
|
+
<InputNumber />
|
|
21
|
+
</Form.Item>
|
|
22
|
+
<Form.Item name={[field.name, "y"]} label="Y">
|
|
23
|
+
<InputNumber />
|
|
24
|
+
</Form.Item>
|
|
25
|
+
<Form.Item name={[field.name, "fontSize"]} label="Size">
|
|
26
|
+
<InputNumber suffix="px"/>
|
|
27
|
+
</Form.Item>
|
|
28
|
+
</Flex>
|
|
29
|
+
</div>))}
|
|
30
|
+
<Flex gap={2}>
|
|
31
|
+
<Button type="primary" onClick={() => add()} className="btn btn-primary">
|
|
32
|
+
Add
|
|
33
|
+
</Button>
|
|
34
|
+
<Button type="primary" onClick={() => remove(fields.length - 1)} className="btn btn-primary">
|
|
35
|
+
Remove
|
|
36
|
+
</Button>
|
|
37
|
+
</Flex>
|
|
38
|
+
</>)}
|
|
39
|
+
</Form.List>
|
|
40
|
+
</Form.Item>
|
|
41
|
+
<div className="divider-dashed"/>
|
|
42
|
+
</div>);
|
|
43
|
+
};
|
|
44
|
+
export default SectionLabel;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ColorPicker, Flex, Form, InputNumber } from "antd";
|
|
3
|
+
const SectionShape = () => {
|
|
4
|
+
return (<div className="py-2">
|
|
5
|
+
<h1 className="heading-s">Shape</h1>
|
|
6
|
+
<Flex gap={2} className="w-full">
|
|
7
|
+
<Form.Item label="Width" name="width" className="w-full">
|
|
8
|
+
<InputNumber suffix="px"/>
|
|
9
|
+
</Form.Item>
|
|
10
|
+
<Form.Item label="Height" name="height" className="w-full">
|
|
11
|
+
<InputNumber suffix="px"/>
|
|
12
|
+
</Form.Item>
|
|
13
|
+
</Flex>
|
|
14
|
+
<Flex gap={2}>
|
|
15
|
+
<Form.Item label="Position X" name="x" className="w-full">
|
|
16
|
+
<InputNumber />
|
|
17
|
+
</Form.Item>
|
|
18
|
+
<Form.Item label="Position Y" name="y" className="w-full">
|
|
19
|
+
<InputNumber />
|
|
20
|
+
</Form.Item>
|
|
21
|
+
<Form.Item label="Rotation" name="rotation" className="w-full">
|
|
22
|
+
<InputNumber />
|
|
23
|
+
</Form.Item>
|
|
24
|
+
</Flex>
|
|
25
|
+
<Flex gap={2}>
|
|
26
|
+
<Form.Item label="Fill" name={"fill"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
|
|
27
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
28
|
+
</Form.Item>
|
|
29
|
+
<Form.Item label="Stroke" name={"stroke"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
|
|
30
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
31
|
+
</Form.Item>
|
|
32
|
+
</Flex>
|
|
33
|
+
<Flex>
|
|
34
|
+
<Form.Item label="Stroke Width" name={"strokeWidth"} className="w-full">
|
|
35
|
+
<InputNumber />
|
|
36
|
+
</Form.Item>
|
|
37
|
+
<Form.Item label="opacity" name={"opacity"} className="w-full">
|
|
38
|
+
<InputNumber step={0.1} max={1} min={0}/>
|
|
39
|
+
</Form.Item>
|
|
40
|
+
</Flex>
|
|
41
|
+
</div>);
|
|
42
|
+
};
|
|
43
|
+
export default SectionShape;
|
|
@@ -21,12 +21,16 @@ const NumberIndicator = ({ name, defaultValue, onChange }) => {
|
|
|
21
21
|
form.setFieldsValue({ [name]: value + 1 });
|
|
22
22
|
onChange(value + 1);
|
|
23
23
|
};
|
|
24
|
-
return (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
return (<Flex gap={2}>
|
|
25
|
+
<Button onClick={handlePrev}>
|
|
26
|
+
<ArrowLeft />
|
|
27
|
+
</Button>
|
|
28
|
+
<Form.Item name={name} noStyle>
|
|
29
|
+
<Input className="flex text-center" type="number" value={value} name={name} onChange={(e) => setValue(parseInt(e.target.value))}/>
|
|
30
|
+
</Form.Item>
|
|
31
|
+
<Button onClick={handleNext}>
|
|
32
|
+
<ArrowRight />
|
|
33
|
+
</Button>
|
|
34
|
+
</Flex>);
|
|
31
35
|
};
|
|
32
36
|
export default NumberIndicator;
|