diff --git a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx index f1f6961e5a..1e73889fb2 100644 --- a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx +++ b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx @@ -11,6 +11,7 @@ import { StrokeLineStyleConfig } from './stroke-line-style-config'; import { Group, UnGroup } from './GroupOperation'; import { DeleteShapes } from './DeleteOperation'; import { Lock, Unlock } from './LockOperation'; +import { FrameFillColorConfig } from './FrameFillColorConfig'; export const CommandPanel: FC<{ app: TldrawApp }> = ({ app }) => { const state = app.useStore(); @@ -51,6 +52,13 @@ export const CommandPanel: FC<{ app: TldrawApp }> = ({ app }) => { shapes={config.fill.selectedShapes} /> ) : null, + frameFill: config.frameFill.selectedShapes.length ? ( + + ) : null, font: config.font.selectedShapes.length ? ( { + const counted = countBy(shapes, shape => shape.style.fill); + const max = maxBy(Object.entries(counted), ([c, n]) => n); + return max[0]; +}; + +export const FrameFillColorConfig: FC = ({ + app, + shapes, +}) => { + const theme = useTheme(); + const setFillColor = (color: ColorType) => { + app.style( + { fill: color, isFilled: color !== 'none' }, + getShapeIds(shapes) + ); + }; + + const iconColor = _getIconRenderColor(shapes); + + return ( + + } + > + + + {iconColor === 'none' ? ( + + ) : ( + + )} + + + + ); +}; diff --git a/libs/components/board-draw/src/components/command-panel/utils/use-config.ts b/libs/components/board-draw/src/components/command-panel/utils/use-config.ts index 05b08b46c6..6071eb8dcc 100644 --- a/libs/components/board-draw/src/components/command-panel/utils/use-config.ts +++ b/libs/components/board-draw/src/components/command-panel/utils/use-config.ts @@ -7,6 +7,7 @@ interface Config { type: | 'stroke' | 'fill' + | 'frameFill' | 'font' | 'group' | 'ungroup' @@ -22,6 +23,10 @@ const _createInitConfig = (): Record => { type: 'fill', selectedShapes: [], }, + frameFill: { + type: 'frameFill', + selectedShapes: [], + }, stroke: { type: 'stroke', selectedShapes: [], @@ -64,6 +69,7 @@ const _isSupportStroke = (shape: TDShape): boolean => { TDShapeType.Pencil, TDShapeType.Laser, TDShapeType.Highlight, + TDShapeType.Draw, TDShapeType.Arrow, TDShapeType.Line, ].some(type => type === shape.type); @@ -91,6 +97,10 @@ const _isSupportFont = (shape: TDShape): boolean => { ].some(type => type === shape.type); }; +const _isSupportFrameFill = (shape: TDShape): boolean => { + return shape.type === TDShapeType.Frame; +}; + export const useConfig = (app: TldrawApp): Record => { const state = app.useStore(); const selectedShapes = TLDR.get_selected_shapes(state, app.currentPageId); @@ -105,6 +115,9 @@ export const useConfig = (app: TldrawApp): Record => { if (_isSupportFont(cur)) { acc.font.selectedShapes.push(cur); } + if (_isSupportFrameFill(cur)) { + acc.frameFill.selectedShapes.push(cur); + } return acc; }, _createInitConfig() diff --git a/libs/components/board-shapes/src/frame-util/frame-util.tsx b/libs/components/board-shapes/src/frame-util/FrameUtil.tsx similarity index 67% rename from libs/components/board-shapes/src/frame-util/frame-util.tsx rename to libs/components/board-shapes/src/frame-util/FrameUtil.tsx index f8db4d09ff..47fc778da7 100644 --- a/libs/components/board-shapes/src/frame-util/frame-util.tsx +++ b/libs/components/board-shapes/src/frame-util/FrameUtil.tsx @@ -1,12 +1,9 @@ -import * as React from 'react'; +/* eslint-disable no-restricted-syntax */ import { Utils, SVGContainer } from '@tldraw/core'; import { FrameShape, - DashStyle, TDShapeType, TDMeta, - GHOSTED_OPACITY, - LABEL_POINT, } from '@toeverything/components/board-types'; import { TDShapeUtil } from '../TDShapeUtil'; import { @@ -14,14 +11,13 @@ import { getShapeStyle, getBoundsRectangle, transformRectangle, - getFontStyle, transformSingleRectangle, } from '../shared'; -import { DrawFrame } from './components/draw-frame'; +import { Frame } from './components/Frame'; import { styled } from '@toeverything/components/ui'; type T = FrameShape; -type E = HTMLDivElement; +type E = SVGSVGElement; export class FrameUtil extends TDShapeUtil { type = TDShapeType.Frame as const; @@ -56,10 +52,7 @@ export class FrameUtil extends TDShapeUtil { ( { shape, - isEditing, - isBinding, isSelected, - isGhost, meta, bounds, events, @@ -70,21 +63,20 @@ export class FrameUtil extends TDShapeUtil { ) => { const { id, size, style } = shape; return ( - - - - - + + + ); } ); @@ -121,27 +113,9 @@ export class FrameUtil extends TDShapeUtil { override transform = transformRectangle; override transformSingle = transformSingleRectangle; - - override hitTestPoint = (shape: T, point: number[]): boolean => { - return false; - }; - - override hitTestLineSegment = ( - shape: T, - A: number[], - B: number[] - ): boolean => { - return false; - }; } const FullWrapper = styled('div')({ width: '100%', height: '100%', - '.tl-fill-hitarea': { - fill: '#F7F9FF', - }, - '.tl-stroke-hitarea': { - fill: '#F7F9FF', - }, }); diff --git a/libs/components/board-shapes/src/frame-util/components/Frame.tsx b/libs/components/board-shapes/src/frame-util/components/Frame.tsx new file mode 100644 index 0000000000..57a6fa878a --- /dev/null +++ b/libs/components/board-shapes/src/frame-util/components/Frame.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; +import { BINDING_DISTANCE } from '@toeverything/components/board-types'; +import type { ShapeStyles } from '@toeverything/components/board-types'; +import { getShapeStyle } from '../../shared'; + +interface RectangleSvgProps { + id: string; + style: ShapeStyles; + isSelected: boolean; + size: number[]; + isDarkMode: boolean; +} + +export const Frame = React.memo(function DashedRectangle({ + id, + style, + size, + isSelected, + isDarkMode, +}: RectangleSvgProps) { + const { strokeWidth, fill } = getShapeStyle(style, isDarkMode); + + const _fill = fill && fill !== 'none' ? fill : '#F7F9FF'; + + const sw = 1 + strokeWidth * 1.618; + + const w = Math.max(0, size[0] - sw / 2); + const h = Math.max(0, size[1] - sw / 2); + + return ( + <> + + + + ); +}); diff --git a/libs/components/board-shapes/src/frame-util/components/draw-frame.tsx b/libs/components/board-shapes/src/frame-util/components/draw-frame.tsx deleted file mode 100644 index 4074f76b15..0000000000 --- a/libs/components/board-shapes/src/frame-util/components/draw-frame.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import * as React from 'react'; -import { BINDING_DISTANCE } from '@toeverything/components/board-types'; -import type { ShapeStyles } from '@toeverything/components/board-types'; -import { getShapeStyle } from '../../shared'; - -interface RectangleSvgProps { - id: string; - style: ShapeStyles; - isSelected: boolean; - size: number[]; - isDarkMode: boolean; -} - -export const DrawFrame = React.memo(function DashedRectangle({ - id, - style, - size, - isSelected, - isDarkMode, -}: RectangleSvgProps) { - const { stroke, strokeWidth, fill } = getShapeStyle(style, isDarkMode); - - const sw = 1 + strokeWidth * 1.618; - - const w = Math.max(0, size[0] - sw / 2); - const h = Math.max(0, size[1] - sw / 2); - - return ( - - ); -}); diff --git a/libs/components/board-shapes/src/frame-util/index.ts b/libs/components/board-shapes/src/frame-util/index.ts index bda0014cda..5401a5fd24 100644 --- a/libs/components/board-shapes/src/frame-util/index.ts +++ b/libs/components/board-shapes/src/frame-util/index.ts @@ -1 +1 @@ -export * from './frame-util'; +export * from './FrameUtil';