From a4195f7482a410274ef8f3c9ddbc4bd8d0992e7e Mon Sep 17 00:00:00 2001 From: pubuzhixing8 Date: Mon, 1 Jul 2024 20:27:10 +0800 Subject: [PATCH] feat: arrow-popup --- .../drawnix/src/components/arrow-popup.tsx | 78 ++++++++++++++++ .../drawnix/src/components/draw-toolbar.tsx | 88 +++++++++++++------ packages/drawnix/src/components/icons.tsx | 27 ++++++ .../drawnix/src/components/shape-picker.scss | 0 .../{shape-picker.tsx => shape-popup.tsx} | 19 +--- 5 files changed, 169 insertions(+), 43 deletions(-) create mode 100644 packages/drawnix/src/components/arrow-popup.tsx delete mode 100644 packages/drawnix/src/components/shape-picker.scss rename packages/drawnix/src/components/{shape-picker.tsx => shape-popup.tsx} (87%) diff --git a/packages/drawnix/src/components/arrow-popup.tsx b/packages/drawnix/src/components/arrow-popup.tsx new file mode 100644 index 0000000..b9da0fe --- /dev/null +++ b/packages/drawnix/src/components/arrow-popup.tsx @@ -0,0 +1,78 @@ +import classNames from 'classnames'; +import { Island } from './island'; +import Stack from './stack'; +import { ToolButton } from './tool-button'; +import { StraightArrowIcon, ElbowArrowIcon, CurveArrowIcon } from './icons'; +import { useBoard } from '@plait/react-board'; +import { BoardTransforms, PlaitBoard } from '@plait/core'; +import * as Popover from '@radix-ui/react-popover'; +import React from 'react'; +import { BoardCreationMode, setCreationMode } from '@plait/common'; +import { LineShape } from '@plait/draw'; + +export interface ArrowProps { + icon: React.ReactNode; + title: string; + pointer: LineShape; +} + +const ARROWS: ArrowProps[] = [ + { + icon: StraightArrowIcon, + title: 'Straight Arrow Line', + pointer: LineShape.straight, + }, + { + icon: ElbowArrowIcon, + title: 'Elbow Arrow Line', + pointer: LineShape.elbow, + }, + { + icon: CurveArrowIcon, + title: 'Curve Arrow Line', + pointer: LineShape.curve, + }, +]; + +export const ArrowPopupContent: React.FC = () => { + const board = useBoard(); + const container = PlaitBoard.getBoardContainer(board); + + const onPointerDown = (pointer: LineShape) => { + setCreationMode(board, BoardCreationMode.drawing); + BoardTransforms.updatePointerType(board, pointer); + }; + + const onPointerUp = () => {}; + + return ( + + + + + {ARROWS.map((arrow, index) => { + return ( + { + onPointerDown(arrow.pointer); + }} + onPointerUp={() => { + onPointerUp(); + }} + /> + ); + })} + + + + + ); +}; diff --git a/packages/drawnix/src/components/draw-toolbar.tsx b/packages/drawnix/src/components/draw-toolbar.tsx index 0c31342..fe05124 100644 --- a/packages/drawnix/src/components/draw-toolbar.tsx +++ b/packages/drawnix/src/components/draw-toolbar.tsx @@ -18,13 +18,20 @@ import { BoardCreationMode, setCreationMode } from '@plait/common'; import { BasicShapes } from '@plait/draw'; import * as Popover from '@radix-ui/react-popover'; import { useSetState } from 'ahooks'; -import { ShapePickerPopupContent } from './shape-picker'; +import { ShapePopupContent } from './shape-popup'; +import { ArrowPopupContent } from './arrow-popup'; + +export enum PopupKey { + 'shape' = 'shape', + 'arrow' = 'arrow', +} type AppToolButtonProps = { title?: string; name?: string; icon: React.ReactNode; pointer?: DrawnixPointerType; + popupKey?: PopupKey; }; const isBasicPointer = (pointer: string) => { @@ -54,17 +61,29 @@ export const BUTTONS: AppToolButtonProps[] = [ pointer: BasicShapes.text, title: 'Text', }, - // { - // name: 'shape', - // icon: ShapeIcon, - // title: 'Shape', - // }, { icon: StraightArrowLineIcon, title: 'Arrow Line', + popupKey: PopupKey.arrow, + }, + { + icon: ShapeIcon, + title: 'Shape', + popupKey: PopupKey.shape, }, ]; +export const renderPopupContent = (key: PopupKey) => { + switch (key) { + case PopupKey.shape: + return ; + case PopupKey.arrow: + return ; + default: + break; + } +}; + export type DrawToolbarProps = { setPointer: (pointer: DrawnixPointerType) => void; }; @@ -72,9 +91,9 @@ export type DrawToolbarProps = { export const DrawToolbar: React.FC = ({ setPointer }) => { const board = useBoard(); - const [state, setState] = useSetState<{ isShapePicker: boolean }>({ - isShapePicker: false, - }); + const [state, setState] = useSetState<{ + popupKey: PopupKey | undefined; + }>({ popupKey: undefined }); const onChange = (pointer: DrawnixPointerType) => { BoardTransforms.updatePointerType(board, pointer); @@ -92,13 +111,44 @@ export const DrawToolbar: React.FC = ({ setPointer }) => { }; const isChecked = (button: AppToolButtonProps) => { - return PlaitBoard.isPointer(board, button.pointer) && !state.isShapePicker; + return ( + PlaitBoard.isPointer(board, button.pointer) && + state.popupKey === undefined + ); }; return ( {BUTTONS.map((button, index) => { + if (button.popupKey) { + return ( + { + if (open) { + setState({ popupKey: button.popupKey }); + } else { + setState({ popupKey: undefined }); + } + }} + > + + + + {renderPopupContent(button.popupKey)} + + ); + } + const buttonComp = ( = ({ setPointer }) => { ); return buttonComp; })} - { - setState({ isShapePicker: open }); - }} - > - - - - - ); diff --git a/packages/drawnix/src/components/icons.tsx b/packages/drawnix/src/components/icons.tsx index 01d3866..e1dc889 100644 --- a/packages/drawnix/src/components/icons.tsx +++ b/packages/drawnix/src/components/icons.tsx @@ -107,3 +107,30 @@ export const RoundRectangleIcon = createIcon( ); + +export const StraightArrowIcon = createIcon( + + + + + +); + +export const ElbowArrowIcon = createIcon( + + + + + +); + +export const CurveArrowIcon = createIcon( + + + + + +); diff --git a/packages/drawnix/src/components/shape-picker.scss b/packages/drawnix/src/components/shape-picker.scss deleted file mode 100644 index e69de29..0000000 diff --git a/packages/drawnix/src/components/shape-picker.tsx b/packages/drawnix/src/components/shape-popup.tsx similarity index 87% rename from packages/drawnix/src/components/shape-picker.tsx rename to packages/drawnix/src/components/shape-popup.tsx index 2e37ee9..8450cc9 100644 --- a/packages/drawnix/src/components/shape-picker.tsx +++ b/packages/drawnix/src/components/shape-popup.tsx @@ -3,12 +3,6 @@ import { Island } from './island'; import Stack from './stack'; import { ToolButton } from './tool-button'; import { - HandIcon, - MindIcon, - SelectionIcon, - ShapeIcon, - TextIcon, - StraightArrowLineIcon, RectangleIcon, EllipseIcon, TriangleIcon, @@ -19,8 +13,6 @@ import { import { useBoard } from '@plait/react-board'; import { BoardTransforms, PlaitBoard } from '@plait/core'; import * as Popover from '@radix-ui/react-popover'; - -import './shape-picker.scss'; import React from 'react'; import { DrawnixPointerType } from '../drawnix'; import { BoardCreationMode, setCreationMode } from '@plait/common'; @@ -75,16 +67,13 @@ const SHAPES: ShapeProps[] = [ const ROW_SHAPES = splitRows(SHAPES, 5); -export type ShapePickerProps = {}; - -export const ShapePickerPopupContent: React.FC = () => { +export const ShapePopupContent: React.FC = () => { const board = useBoard(); const container = PlaitBoard.getBoardContainer(board); const onPointerDown = (pointer: DrawnixPointerType) => { setCreationMode(board, BoardCreationMode.dnd); BoardTransforms.updatePointerType(board, pointer); - // setPointer(pointer); }; const onPointerUp = () => { @@ -96,14 +85,14 @@ export const ShapePickerPopupContent: React.FC = () => { - {ROW_SHAPES.map((shapes, rowIndex) => { + {ROW_SHAPES.map((rowShapes, rowIndex) => { return ( - {shapes.map((shape, index) => { + {rowShapes.map((shape, index) => { return (