diff --git a/libs/components/board-commands/src/index.ts b/libs/components/board-commands/src/index.ts index b10d3f2f9f..62314e9264 100644 --- a/libs/components/board-commands/src/index.ts +++ b/libs/components/board-commands/src/index.ts @@ -22,3 +22,4 @@ export * from './translate-shapes'; export * from './ungroup-shapes'; export * from './update-shapes'; export * from './set-shapes-props'; +export * from './set-shapes-lock-status'; diff --git a/libs/components/board-commands/src/set-shapes-lock-status.ts b/libs/components/board-commands/src/set-shapes-lock-status.ts new file mode 100644 index 0000000000..ea220e1ea1 --- /dev/null +++ b/libs/components/board-commands/src/set-shapes-lock-status.ts @@ -0,0 +1,59 @@ +import type { + TDShape, + TldrawCommand, +} from '@toeverything/components/board-types'; +import type { TldrawApp } from '@toeverything/components/board-state'; + +export function setShapesLockStatus( + app: TldrawApp, + ids: string[], + isLocked: boolean +): TldrawCommand { + const { currentPageId, selectedIds } = app; + + const initialShapes = ids.map(id => app.getShape(id)); + + const before: Record> = {}; + const after: Record> = {}; + + initialShapes.forEach(shape => { + before[shape.id] = { + isLocked: shape.isLocked, + }; + after[shape.id] = { + isLocked, + }; + }); + + return { + id: 'set_shapes_lock_status', + before: { + document: { + pages: { + [currentPageId]: { + shapes: before, + }, + }, + pageStates: { + [currentPageId]: { + selectedIds, + }, + }, + }, + }, + after: { + document: { + pages: { + [currentPageId]: { + shapes: after, + }, + }, + pageStates: { + [currentPageId]: { + selectedIds, + }, + }, + }, + }, + }; +} 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 3fc6e98f85..6360f402ef 100644 --- a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx +++ b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx @@ -9,6 +9,7 @@ import { FontSizeConfig } from './FontSizeConfig'; import { StrokeLineStyleConfig } from './stroke-line-style-config'; import { Group, UnGroup } from './GroupOperation'; import { DeleteShapes } from './DeleteOperation'; +import { Lock, Unlock } from './LockOperation'; export const CommandPanel: FC<{ app: TldrawApp }> = ({ app }) => { const state = app.useStore(); @@ -63,6 +64,16 @@ export const CommandPanel: FC<{ app: TldrawApp }> = ({ app }) => { shapes={config.ungroup.selectedShapes} /> ) : null, + lock: config.lock.selectedShapes.length ? ( + + ) : null, + unlock: config.unlock.selectedShapes.length ? ( + + ) : null, delete: ( = ({ app, shapes }) => { + const lock = () => { + app.lock(getShapeIds(shapes)); + }; + return ( + + + + + + ); +}; + +export const Unlock: FC = ({ app, shapes }) => { + const unlock = () => { + app.unlock(getShapeIds(shapes)); + }; + + return ( + + + + + + ); +}; 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 4378ba3460..05b08b46c6 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 @@ -4,7 +4,15 @@ import { TDShapeType } from '@toeverything/components/board-types'; import { TLDR } from '@toeverything/components/board-state'; interface Config { - type: 'stroke' | 'fill' | 'font' | 'group' | 'ungroup' | 'deleteShapes'; + type: + | 'stroke' + | 'fill' + | 'font' + | 'group' + | 'ungroup' + | 'deleteShapes' + | 'lock' + | 'unlock'; selectedShapes: TDShape[]; } @@ -34,6 +42,14 @@ const _createInitConfig = (): Record => { type: 'deleteShapes', selectedShapes: [], }, + lock: { + type: 'lock', + selectedShapes: [], + }, + unlock: { + type: 'unlock', + selectedShapes: [], + }, }; }; @@ -64,6 +80,17 @@ const _isSupportFill = (shape: TDShape): boolean => { ].some(type => type === shape.type); }; +const _isSupportFont = (shape: TDShape): boolean => { + return [ + TDShapeType.Rectangle, + TDShapeType.Ellipse, + TDShapeType.Hexagon, + TDShapeType.Triangle, + TDShapeType.WhiteArrow, + TDShapeType.Pentagram, + ].some(type => type === shape.type); +}; + export const useConfig = (app: TldrawApp): Record => { const state = app.useStore(); const selectedShapes = TLDR.get_selected_shapes(state, app.currentPageId); @@ -74,6 +101,8 @@ export const useConfig = (app: TldrawApp): Record => { } if (_isSupportFill(cur)) { acc.fill.selectedShapes.push(cur); + } + if (_isSupportFont(cur)) { acc.font.selectedShapes.push(cur); } return acc; @@ -81,6 +110,7 @@ export const useConfig = (app: TldrawApp): Record => { _createInitConfig() ); + // group if ( selectedShapes.length === 1 && selectedShapes[0].type === TDShapeType.Group @@ -91,6 +121,13 @@ export const useConfig = (app: TldrawApp): Record => { config.group.selectedShapes = selectedShapes; } + // lock + if (selectedShapes.length === 1 && selectedShapes[0].isLocked) { + config.unlock.selectedShapes = selectedShapes; + } else { + config.lock.selectedShapes = selectedShapes; + } + config.deleteShapes.selectedShapes = selectedShapes; return config; diff --git a/libs/components/board-state/src/tldraw-app.ts b/libs/components/board-state/src/tldraw-app.ts index b0c3755e5f..9ad3377540 100644 --- a/libs/components/board-state/src/tldraw-app.ts +++ b/libs/components/board-state/src/tldraw-app.ts @@ -3577,6 +3577,24 @@ export class TldrawApp extends StateManager { ); }; + lock = (ids = this.selectedIds): this => { + if (ids.length === 0) { + return this; + } + return this.set_state( + this.commands.setShapesLockStatus(this, ids, true) + ); + }; + + unlock = (ids = this.selectedIds): this => { + if (ids.length === 0) { + return this; + } + return this.set_state( + this.commands.setShapesLockStatus(this, ids, false) + ); + }; + /** * Toggle the fixed-aspect-ratio property of one or more shapes. * @param ids The ids to change (defaults to selection). diff --git a/libs/components/board-state/src/types/commands.ts b/libs/components/board-state/src/types/commands.ts index 718108cc53..5a26a22788 100644 --- a/libs/components/board-state/src/types/commands.ts +++ b/libs/components/board-state/src/types/commands.ts @@ -102,4 +102,9 @@ export interface Commands { updates: ({ id: string } & Partial)[], pageId: string ): TldrawCommand; + setShapesLockStatus( + app: TldrawApp, + ids: string[], + isLocked: boolean + ): TldrawCommand; }