@likec4/diagram 1.7.3 → 1.7.4

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/index.mjs CHANGED
@@ -55,7 +55,7 @@ const useXYStoreApi = useStoreApi, ZIndexes = {
55
55
  Compound: 2,
56
56
  Edge: 4,
57
57
  Element: 6
58
- }, MinZoom = 0.1;
58
+ }, MinZoom = 0.1, MaxZoom = 2;
59
59
  function toDomPrecision(v) {
60
60
  return v === null ? 0.01 : Math.round(v * 100) / 100;
61
61
  }
@@ -2016,10 +2016,13 @@ function useXYFlowEvents() {
2016
2016
  onDoubleClick: (event) => {
2017
2017
  const {
2018
2018
  onCanvasDblClick,
2019
+ zoomable,
2019
2020
  xystore,
2021
+ viewportChanged,
2022
+ fitDiagram,
2020
2023
  resetLastClicked
2021
2024
  } = diagramApi.getState();
2022
- resetLastClicked(), xystore.getState().resetSelectedElements(), onCanvasDblClick || event.stopPropagation(), onCanvasDblClick == null || onCanvasDblClick(event);
2025
+ resetLastClicked(), xystore.getState().resetSelectedElements(), onCanvasDblClick || event.stopPropagation(), zoomable && viewportChanged && fitDiagram(), onCanvasDblClick == null || onCanvasDblClick(event);
2023
2026
  },
2024
2027
  onPaneClick: (event) => {
2025
2028
  if (dbclickLock())
@@ -2233,11 +2236,11 @@ function XYFlow({
2233
2236
  hasOnEdgeContextMenu,
2234
2237
  translateX,
2235
2238
  translateY
2236
- } = useDiagramState(selector$1, shallowEqual), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents();
2239
+ } = useDiagramState(selector$1, shallowEqual), [zoomOnDoubleClick, setZoomOnDoubleClick] = useState(zoomable), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents();
2237
2240
  return useOnViewportChange({
2238
2241
  onEnd: ({ x, y, zoom }) => {
2239
2242
  const roundedX = Math.round(x), roundedY = Math.round(y);
2240
- (x !== roundedX || y !== roundedY) && xyflowApi.setState({ transform: [roundedX, roundedY, zoom] });
2243
+ (x !== roundedX || y !== roundedY) && xyflowApi.setState({ transform: [roundedX, roundedY, zoom] }), setZoomOnDoubleClick(zoomable && zoom < 1.1);
2241
2244
  }
2242
2245
  }), /* @__PURE__ */ jsx(
2243
2246
  ReactFlow,
@@ -2254,7 +2257,7 @@ function XYFlow({
2254
2257
  ...!zoomable && {
2255
2258
  zoomActivationKeyCode: null
2256
2259
  },
2257
- maxZoom: zoomable ? 1.9 : 1,
2260
+ maxZoom: zoomable ? MaxZoom : 1,
2258
2261
  minZoom: zoomable ? MinZoom : 1,
2259
2262
  fitView,
2260
2263
  fitViewOptions: useMemo(() => ({
@@ -2289,7 +2292,7 @@ function XYFlow({
2289
2292
  onNodeDragStop: layoutConstraints.onNodeDragStop
2290
2293
  },
2291
2294
  nodeDragThreshold: 3,
2292
- zoomOnDoubleClick: zoomable,
2295
+ zoomOnDoubleClick,
2293
2296
  elevateNodesOnSelect: !1,
2294
2297
  selectNodesOnDrag: !1,
2295
2298
  onNodesChange,
@@ -2350,62 +2353,75 @@ function DiagramTitlePanel() {
2350
2353
  radius: "sm",
2351
2354
  className: card,
2352
2355
  withBorder: !0,
2353
- p: "md",
2354
- pb: isCollapsed ? "sm" : "md",
2356
+ p: isCollapsed ? "sm" : "md",
2355
2357
  onDoubleClick: (e) => e.stopPropagation(),
2356
2358
  children: [
2357
- /* @__PURE__ */ jsx(CardSection, { mb: isCollapsed ? 10 : "sm", children: /* @__PURE__ */ jsx(
2359
+ isCollapsed && /* @__PURE__ */ jsx(CardSection, { children: /* @__PURE__ */ jsx(
2358
2360
  Button,
2359
2361
  {
2360
2362
  fullWidth: !0,
2361
- size: "xs",
2362
- h: "sm",
2363
+ justify: "stretch",
2364
+ size: "sm",
2363
2365
  py: 2,
2364
2366
  radius: "0",
2365
- variant: isCollapsed ? "light" : "subtle",
2366
- color: "gray",
2367
+ variant: "subtle",
2368
+ color: "dark",
2367
2369
  onClick: toggle,
2368
- children: /* @__PURE__ */ jsx(IconMenu, { size: 11, opacity: 0.7 })
2370
+ children: /* @__PURE__ */ jsx(Text$1, { inline: !0, fw: 500, fz: "xs", c: "gray", children: title$12 })
2369
2371
  }
2370
2372
  ) }),
2371
- /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", mb: isCollapsed ? 0 : "sm", children: [
2372
- /* @__PURE__ */ jsx(
2373
- Text$1,
2374
- {
2375
- component: "div",
2376
- flex: "1",
2377
- size: isCollapsed ? "sm" : "lg",
2378
- fw: 500,
2379
- lh: 1.1,
2380
- className: title,
2381
- children: title$12
2382
- }
2383
- ),
2384
- /* @__PURE__ */ jsxs(
2385
- Text$1,
2373
+ !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
2374
+ /* @__PURE__ */ jsx(CardSection, { mb: "sm", children: /* @__PURE__ */ jsx(
2375
+ Button,
2386
2376
  {
2387
- hidden: isCollapsed,
2388
- component: "div",
2389
- flex: "0 0 auto",
2390
- inline: !0,
2377
+ fullWidth: !0,
2391
2378
  size: "xs",
2392
- fz: 9,
2393
- fw: 500,
2394
- c: "dimmed",
2395
- style: {
2396
- userSelect: "all"
2397
- },
2398
- children: [
2399
- /* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
2400
- "id:",
2401
- " "
2402
- ] }),
2403
- id
2404
- ]
2379
+ h: "sm",
2380
+ py: 2,
2381
+ radius: "0",
2382
+ variant: "subtle",
2383
+ color: "gray",
2384
+ onClick: toggle,
2385
+ children: /* @__PURE__ */ jsx(IconMenu, { size: 11, opacity: 0.7 })
2405
2386
  }
2406
- )
2407
- ] }),
2408
- !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
2387
+ ) }),
2388
+ /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", mb: "sm", children: [
2389
+ /* @__PURE__ */ jsx(
2390
+ Text$1,
2391
+ {
2392
+ component: "div",
2393
+ flex: "1",
2394
+ size: "md",
2395
+ fw: 500,
2396
+ lh: 1.1,
2397
+ className: title,
2398
+ children: title$12
2399
+ }
2400
+ ),
2401
+ /* @__PURE__ */ jsxs(
2402
+ Text$1,
2403
+ {
2404
+ hidden: isCollapsed,
2405
+ component: "div",
2406
+ flex: "0 0 auto",
2407
+ inline: !0,
2408
+ size: "xs",
2409
+ fz: 9,
2410
+ fw: 500,
2411
+ c: "dimmed",
2412
+ style: {
2413
+ userSelect: "all"
2414
+ },
2415
+ children: [
2416
+ /* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
2417
+ "id:",
2418
+ " "
2419
+ ] }),
2420
+ id
2421
+ ]
2422
+ }
2423
+ )
2424
+ ] }),
2409
2425
  description$12 && /* @__PURE__ */ jsx(
2410
2426
  Spoiler,
2411
2427
  {
package/dist/style.css CHANGED
@@ -1992,13 +1992,13 @@ drop-shadow(1px 1px 16px rgb(0 0 0 / 3%))
1992
1992
  }
1993
1993
  @media (min-width: 48em) {
1994
1994
  .hbkbtj1 {
1995
- min-width: 300px;
1995
+ min-width: 250px;
1996
1996
  max-width: 90vw;
1997
1997
  }
1998
1998
  }
1999
1999
  @media (min-width: 62em) {
2000
2000
  .hbkbtj1 {
2001
- min-width: 400px;
2001
+ min-width: 350px;
2002
2002
  max-width: 70vw;
2003
2003
  }
2004
2004
  }._2jkb2y0 {
@@ -4,3 +4,4 @@ export declare const ZIndexes: {
4
4
  readonly Element: 6;
5
5
  };
6
6
  export declare const MinZoom = 0.1;
7
+ export declare const MaxZoom = 2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/diagram",
3
- "version": "1.7.3",
3
+ "version": "1.7.4",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://likec4.dev",
@@ -66,15 +66,15 @@
66
66
  "zustand": "^4.5.4"
67
67
  },
68
68
  "peerDependencies": {
69
- "@likec4/core": "1.7.3",
69
+ "@likec4/core": "1.7.4",
70
70
  "@mantine/core": "^7.11.2",
71
71
  "@mantine/hooks": "^7.11.2",
72
72
  "react": "^18.3.1",
73
73
  "react-dom": "^18.3.1"
74
74
  },
75
75
  "devDependencies": {
76
- "@likec4/core": "1.7.3",
77
- "@likec4/tsconfig": "1.7.3",
76
+ "@likec4/core": "1.7.4",
77
+ "@likec4/tsconfig": "1.7.4",
78
78
  "@mantine/core": "7.11.2",
79
79
  "@mantine/hooks": "7.11.2",
80
80
  "@mantine/vanilla-extract": "7.11.2",
@@ -18,11 +18,11 @@ export const card = style({
18
18
  backdropFilter: fallbackVar(vars.safariAnimationHook, 'blur(8px)'),
19
19
  '@media': {
20
20
  [mantine.largerThan('sm')]: {
21
- minWidth: 300,
21
+ minWidth: 250,
22
22
  maxWidth: '90vw'
23
23
  },
24
24
  [mantine.largerThan('md')]: {
25
- minWidth: 400,
25
+ minWidth: 350,
26
26
  maxWidth: '70vw'
27
27
  }
28
28
  },
@@ -40,52 +40,70 @@ export default function DiagramTitlePanel() {
40
40
  radius="sm"
41
41
  className={css.card}
42
42
  withBorder
43
- p={'md'}
44
- pb={isCollapsed ? 'sm' : 'md'}
43
+ p={isCollapsed ? 'sm' : 'md'}
45
44
  onDoubleClick={e => e.stopPropagation()}>
46
- <CardSection mb={isCollapsed ? 10 : 'sm'}>
47
- <Button
48
- fullWidth
49
- size="xs"
50
- h={'sm'}
51
- py={2}
52
- radius={'0'}
53
- variant={isCollapsed ? 'light' : 'subtle'}
54
- color="gray"
55
- onClick={toggle}
56
- >
57
- <IconMenu size={11} opacity={0.7} />
58
- </Button>
59
- </CardSection>
60
- <Group justify="stretch" wrap="nowrap" mb={isCollapsed ? 0 : 'sm'}>
61
- <Text
62
- component={'div'}
63
- flex={'1'}
64
- size={isCollapsed ? 'sm' : 'lg'}
65
- fw={500}
66
- lh={1.1}
67
- className={css.title}
68
- >
69
- {title}
70
- </Text>
71
- <Text
72
- hidden={isCollapsed}
73
- component={'div'}
74
- flex={'0 0 auto'}
75
- inline
76
- size="xs"
77
- fz={9}
78
- fw={500}
79
- c={'dimmed'}
80
- style={{
81
- userSelect: 'all'
82
- }}>
83
- <span style={{ userSelect: 'none' }}>id:{' '}</span>
84
- {id}
85
- </Text>
86
- </Group>
45
+ {isCollapsed && (
46
+ <CardSection>
47
+ <Button
48
+ fullWidth
49
+ justify="stretch"
50
+ size="sm"
51
+ py={2}
52
+ radius={'0'}
53
+ variant={'subtle'}
54
+ color="dark"
55
+ onClick={toggle}
56
+ >
57
+ <Text inline fw={500} fz={'xs'} c="gray">
58
+ {title}
59
+ </Text>
60
+ </Button>
61
+ </CardSection>
62
+ )}
87
63
  {!isCollapsed && (
88
64
  <>
65
+ <CardSection mb={'sm'}>
66
+ <Button
67
+ fullWidth
68
+ size="xs"
69
+ h={'sm'}
70
+ py={2}
71
+ radius={'0'}
72
+ variant={'subtle'}
73
+ color="gray"
74
+ onClick={toggle}
75
+ >
76
+ <IconMenu size={11} opacity={0.7} />
77
+ </Button>
78
+ </CardSection>
79
+
80
+ <Group justify="stretch" wrap="nowrap" mb={'sm'}>
81
+ <Text
82
+ component={'div'}
83
+ flex={'1'}
84
+ size={'md'}
85
+ fw={500}
86
+ lh={1.1}
87
+ className={css.title}
88
+ >
89
+ {title}
90
+ </Text>
91
+ <Text
92
+ hidden={isCollapsed}
93
+ component={'div'}
94
+ flex={'0 0 auto'}
95
+ inline
96
+ size="xs"
97
+ fz={9}
98
+ fw={500}
99
+ c={'dimmed'}
100
+ style={{
101
+ userSelect: 'all'
102
+ }}>
103
+ <span style={{ userSelect: 'none' }}>id:{' '}</span>
104
+ {id}
105
+ </Text>
106
+ </Group>
89
107
  {description && (
90
108
  <Spoiler
91
109
  maxHeight={42}
@@ -1,10 +1,10 @@
1
1
  import { ReactFlow, useOnViewportChange } from '@xyflow/react'
2
2
  import { shallowEqual } from 'fast-equals'
3
- import { type CSSProperties, type PropsWithChildren, useMemo } from 'react'
3
+ import { type CSSProperties, type PropsWithChildren, useMemo, useState } from 'react'
4
4
  import { useDiagramState } from '../hooks/useDiagramState'
5
5
  import { useXYStoreApi } from '../hooks/useXYFlow'
6
6
  import type { DiagramState } from '../state/diagramStore'
7
- import { MinZoom } from './const'
7
+ import { MaxZoom, MinZoom } from './const'
8
8
  import { RelationshipEdge } from './edges/RelationshipEdge'
9
9
  import { CompoundNode } from './nodes/compound'
10
10
  import { ElementNode } from './nodes/element'
@@ -87,6 +87,7 @@ export function XYFlow({
87
87
  translateX,
88
88
  translateY
89
89
  } = useDiagramState(selector, shallowEqual)
90
+ const [zoomOnDoubleClick, setZoomOnDoubleClick] = useState(zoomable)
90
91
 
91
92
  // useLogger('XYFlow',[
92
93
  // nodes,
@@ -110,6 +111,7 @@ export function XYFlow({
110
111
  if (x !== roundedX || y !== roundedY) {
111
112
  xyflowApi.setState({ transform: [roundedX, roundedY, zoom] })
112
113
  }
114
+ setZoomOnDoubleClick(zoomable && zoom < 1.1)
113
115
  }
114
116
  })
115
117
 
@@ -127,7 +129,7 @@ export function XYFlow({
127
129
  {...(!zoomable && {
128
130
  zoomActivationKeyCode: null
129
131
  })}
130
- maxZoom={zoomable ? 1.9 : 1}
132
+ maxZoom={zoomable ? MaxZoom : 1}
131
133
  minZoom={zoomable ? MinZoom : 1}
132
134
  fitView={fitView}
133
135
  fitViewOptions={useMemo(() => ({
@@ -162,7 +164,7 @@ export function XYFlow({
162
164
  onNodeDragStop: layoutConstraints.onNodeDragStop
163
165
  }}
164
166
  nodeDragThreshold={3}
165
- zoomOnDoubleClick={zoomable}
167
+ zoomOnDoubleClick={zoomOnDoubleClick}
166
168
  elevateNodesOnSelect={false} // or edges are not visible after select\
167
169
  selectNodesOnDrag={false}
168
170
  onNodesChange={onNodesChange}
@@ -58,7 +58,10 @@ export function useXYFlowEvents() {
58
58
  onDoubleClick: (event) => {
59
59
  const {
60
60
  onCanvasDblClick,
61
+ zoomable,
61
62
  xystore,
63
+ viewportChanged,
64
+ fitDiagram,
62
65
  resetLastClicked
63
66
  } = diagramApi.getState()
64
67
  resetLastClicked()
@@ -66,6 +69,9 @@ export function useXYFlowEvents() {
66
69
  if (!onCanvasDblClick) {
67
70
  event.stopPropagation()
68
71
  }
72
+ if (zoomable && viewportChanged) {
73
+ fitDiagram()
74
+ }
69
75
  onCanvasDblClick?.(event)
70
76
  },
71
77
  onPaneClick: (event) => {
@@ -5,3 +5,4 @@ export const ZIndexes = {
5
5
  } as const
6
6
 
7
7
  export const MinZoom = 0.1
8
+ export const MaxZoom = 2