@likec4/diagram 1.22.0 → 1.22.1

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.
@@ -1,5 +1,5 @@
1
1
  import type { ViewChange, ViewId } from '@likec4/core'
2
- import { boxToRect, getBoundsOfRects, getNodeDimensions } from '@xyflow/system'
2
+ import { type Rect, boxToRect, getBoundsOfRects, getNodeDimensions } from '@xyflow/system'
3
3
  import { hasAtLeast, reduce } from 'remeda'
4
4
  import {
5
5
  type ActorRef,
@@ -132,12 +132,7 @@ function createViewChange(parentContext: Machine.DiagramContext): ViewChange.Sav
132
132
 
133
133
  const { nodeLookup } = xystore.getState()
134
134
  const movedNodes = new Set<string>()
135
- let bounds = {
136
- x: 0,
137
- y: 0,
138
- width: 1,
139
- height: 1,
140
- }
135
+ let bounds: Rect | undefined
141
136
 
142
137
  const nodes = reduce([...nodeLookup.values()], (acc, node) => {
143
138
  const dimensions = getNodeDimensions(node)
@@ -154,7 +149,7 @@ function createViewChange(parentContext: Machine.DiagramContext): ViewChange.Sav
154
149
  width: Math.ceil(dimensions.width),
155
150
  height: Math.ceil(dimensions.height),
156
151
  }
157
- bounds = getBoundsOfRects(bounds, rect)
152
+ bounds = bounds ? getBoundsOfRects(bounds, rect) : rect
158
153
  return acc
159
154
  }, {} as ViewChange.SaveManualLayout['layout']['nodes'])
160
155
 
@@ -202,10 +197,12 @@ function createViewChange(parentContext: Machine.DiagramContext): ViewChange.Sav
202
197
  x2: Math.ceil(Math.max(...allX)),
203
198
  y2: Math.ceil(Math.max(...allY)),
204
199
  })
205
- bounds = getBoundsOfRects(bounds, rect)
200
+ bounds = bounds ? getBoundsOfRects(bounds, rect) : rect
206
201
  return acc
207
202
  }, {} as ViewChange.SaveManualLayout['layout']['edges'])
208
203
 
204
+ bounds ??= view.bounds
205
+
209
206
  return {
210
207
  op: 'save-manual-layout',
211
208
  layout: {
@@ -16,6 +16,7 @@ import { LayoutDriftNotification } from './LayoutDriftNotification'
16
16
  import { ManualLayoutToolsButton } from './ManualLayoutToolsButton'
17
17
  import { NavigationButtons } from './NavigationButtons'
18
18
  import * as css from './styles.css'
19
+ import { ToggleReadonly } from './ToggleReadonly'
19
20
 
20
21
  export const Controls = memo(() => {
21
22
  const { viewId, hasLayoutDrift, viewportChanged } = useDiagramContext(c => ({
@@ -78,6 +79,7 @@ export const Controls = memo(() => {
78
79
  </ActionIcon>
79
80
  </Tooltip>
80
81
  )}
82
+ {enableControls && <ToggleReadonly />}
81
83
  {enableControls && hasLayoutDrift && <LayoutDriftNotification {...portalProps} />}
82
84
  {enableControls && notReadOnly && (
83
85
  <>
@@ -0,0 +1,31 @@
1
+ import { IconLock, IconLockOpen2 } from '@tabler/icons-react'
2
+ import { useDiagram } from '../../../hooks/useDiagram'
3
+ import { useDiagramContext } from '../../../hooks/useDiagramContext'
4
+ import type { DiagramContext } from '../../state/machine'
5
+ import { ActionIcon, Tooltip } from './_shared'
6
+
7
+ const selector = (state: DiagramContext) => ({
8
+ visible: state.features.enableReadOnly !== true,
9
+ isReadOnly: state.toggledFeatures.enableReadOnly ?? state.features.enableReadOnly,
10
+ })
11
+
12
+ export const ToggleReadonly = () => {
13
+ const { visible, isReadOnly } = useDiagramContext(selector)
14
+ const diagram = useDiagram()
15
+
16
+ if (!visible) {
17
+ return null
18
+ }
19
+
20
+ return (
21
+ <Tooltip label={isReadOnly ? 'Enable editing' : 'Disable editing'}>
22
+ <ActionIcon
23
+ onClick={e => {
24
+ e.stopPropagation()
25
+ diagram.toggleFeature('ReadOnly')
26
+ }}>
27
+ {isReadOnly ? <IconLock /> : <IconLockOpen2 />}
28
+ </ActionIcon>
29
+ </Tooltip>
30
+ )
31
+ }