@likec4/diagram 1.42.1 → 1.43.0

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.
@@ -0,0 +1,261 @@
1
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
+ import { css } from '@likec4/styles/css';
3
+ import { UnstyledButton, Flex, Text, Box, Stack, Tooltip } from '@mantine/core';
4
+ import { useState, useRef, useEffect } from 'react';
5
+ import IconChevronDown from '../../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronDown.js';
6
+ import IconChevronRight from '../../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.js';
7
+
8
+ function MetadataProvider({ children }) {
9
+ return /* @__PURE__ */ jsx(Fragment, { children });
10
+ }
11
+ function TruncatedValue({ value, isExpanded }) {
12
+ const [isTruncated, setIsTruncated] = useState(false);
13
+ const textRef = useRef(null);
14
+ useEffect(() => {
15
+ if (textRef.current) {
16
+ setIsTruncated(textRef.current.scrollWidth > textRef.current.clientWidth);
17
+ }
18
+ }, [value]);
19
+ return /* @__PURE__ */ jsx(
20
+ Tooltip,
21
+ {
22
+ label: isTruncated && !isExpanded ? value : null,
23
+ multiline: true,
24
+ w: 300,
25
+ withinPortal: true,
26
+ children: /* @__PURE__ */ jsx(
27
+ Text,
28
+ {
29
+ ref: textRef,
30
+ component: "div",
31
+ className: css({
32
+ fontSize: "sm",
33
+ padding: "xs",
34
+ userSelect: "all",
35
+ color: "mantine.colors.text",
36
+ lineHeight: 1.4,
37
+ whiteSpace: isExpanded ? "pre-wrap" : "nowrap",
38
+ overflow: isExpanded ? "visible" : "hidden",
39
+ textOverflow: isExpanded ? "unset" : "ellipsis",
40
+ wordBreak: isExpanded ? "break-word" : "normal",
41
+ minWidth: 0,
42
+ width: "100%"
43
+ }),
44
+ children: value
45
+ }
46
+ )
47
+ }
48
+ );
49
+ }
50
+ function MultiValueDisplay({
51
+ values,
52
+ isExpanded,
53
+ onToggle
54
+ }) {
55
+ if (isExpanded) {
56
+ return /* @__PURE__ */ jsx(Stack, { gap: "xs", children: values.map((value, index) => /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", children: [
57
+ /* @__PURE__ */ jsx(
58
+ Text,
59
+ {
60
+ className: css({
61
+ fontSize: "xs",
62
+ color: "mantine.colors.gray[5]",
63
+ fontWeight: 500,
64
+ flexShrink: 0,
65
+ _dark: {
66
+ color: "mantine.colors.dark[3]"
67
+ }
68
+ }),
69
+ children: "•"
70
+ }
71
+ ),
72
+ /* @__PURE__ */ jsx(
73
+ Box,
74
+ {
75
+ className: css({
76
+ minHeight: "32px",
77
+ display: "flex",
78
+ alignItems: "center",
79
+ flex: 1
80
+ }),
81
+ children: /* @__PURE__ */ jsx(TruncatedValue, { value, isExpanded: true })
82
+ }
83
+ )
84
+ ] }, index)) });
85
+ }
86
+ return /* @__PURE__ */ jsx(
87
+ Box,
88
+ {
89
+ className: css({
90
+ minHeight: "32px",
91
+ display: "flex",
92
+ alignItems: "center",
93
+ padding: "xs",
94
+ gap: "xs",
95
+ flexWrap: "wrap",
96
+ minWidth: 0,
97
+ // Allow shrinking
98
+ overflow: "hidden"
99
+ // Prevent overflow
100
+ }),
101
+ children: values.map((value, index) => /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", style: { minWidth: 0 }, children: [
102
+ /* @__PURE__ */ jsx(
103
+ Text,
104
+ {
105
+ className: css({
106
+ fontSize: "sm",
107
+ padding: "[4px 8px]",
108
+ backgroundColor: "mantine.colors.white",
109
+ color: "mantine.colors.text",
110
+ borderRadius: "sm",
111
+ border: "1px solid",
112
+ borderColor: "mantine.colors.gray[3]",
113
+ whiteSpace: "nowrap",
114
+ overflow: "hidden",
115
+ textOverflow: "ellipsis",
116
+ maxWidth: "min(200px, 100%)",
117
+ minWidth: "60px",
118
+ flex: "0 1 auto",
119
+ userSelect: "all",
120
+ _dark: {
121
+ backgroundColor: "mantine.colors.dark[9]",
122
+ color: "mantine.colors.text",
123
+ borderColor: "mantine.colors.dark[4]"
124
+ }
125
+ }),
126
+ title: value,
127
+ children: value
128
+ }
129
+ ),
130
+ index < values.length - 1 && /* @__PURE__ */ jsx(
131
+ Text,
132
+ {
133
+ className: css({
134
+ fontSize: "xs",
135
+ color: "mantine.colors.gray[5]",
136
+ fontWeight: 500,
137
+ flexShrink: 0,
138
+ _dark: {
139
+ color: "mantine.colors.dark[3]"
140
+ }
141
+ }),
142
+ children: "•"
143
+ }
144
+ )
145
+ ] }, index))
146
+ }
147
+ );
148
+ }
149
+ function MetadataValue({ label, value }) {
150
+ const elements = Array.isArray(value) ? value : typeof value === "string" && value.includes("\n") ? value.split("\n").map((s) => s.trim()).filter(Boolean) : [value];
151
+ const hasMultipleElements = elements.length > 1;
152
+ const [isExpanded, setIsExpanded] = useState(false);
153
+ const handleToggle = () => {
154
+ setIsExpanded(!isExpanded);
155
+ };
156
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
157
+ hasMultipleElements ? /* @__PURE__ */ jsx(
158
+ UnstyledButton,
159
+ {
160
+ onClick: handleToggle,
161
+ className: css({
162
+ fontSize: "xs",
163
+ color: "mantine.colors.dimmed",
164
+ justifySelf: "end",
165
+ textAlign: "right",
166
+ userSelect: "none",
167
+ display: "flex",
168
+ alignItems: "center",
169
+ justifyContent: "flex-end",
170
+ gap: "xs",
171
+ padding: "[4px 8px]",
172
+ borderRadius: "sm",
173
+ whiteSpace: "nowrap",
174
+ transition: "all 150ms ease",
175
+ _hover: {
176
+ backgroundColor: "mantine.colors.gray[1]",
177
+ color: "mantine.colors.primary[6]",
178
+ _dark: {
179
+ backgroundColor: "mantine.colors.dark[7]",
180
+ color: "mantine.colors.primary[4]"
181
+ }
182
+ }
183
+ }),
184
+ children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", children: [
185
+ /* @__PURE__ */ jsxs(Text, { component: "span", size: "xs", fw: 700, children: [
186
+ label,
187
+ ":"
188
+ ] }),
189
+ /* @__PURE__ */ jsx(
190
+ Text,
191
+ {
192
+ component: "span",
193
+ className: css({
194
+ fontSize: "xs",
195
+ fontWeight: 500,
196
+ color: "mantine.colors.gray[6]",
197
+ backgroundColor: "mantine.colors.gray[1]",
198
+ padding: "[1px 4px]",
199
+ borderRadius: "xs",
200
+ _dark: {
201
+ color: "mantine.colors.dark[2]",
202
+ backgroundColor: "mantine.colors.dark[6]"
203
+ }
204
+ }),
205
+ children: elements.length
206
+ }
207
+ ),
208
+ isExpanded ? /* @__PURE__ */ jsx(IconChevronDown, { size: 12 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 12 })
209
+ ] })
210
+ }
211
+ ) : /* @__PURE__ */ jsxs(
212
+ Text,
213
+ {
214
+ component: "div",
215
+ className: css({
216
+ fontSize: "xs",
217
+ color: "mantine.colors.dimmed",
218
+ justifySelf: "end",
219
+ textAlign: "right",
220
+ userSelect: "none",
221
+ whiteSpace: "nowrap",
222
+ padding: "[4px 8px]",
223
+ fontWeight: 700
224
+ }),
225
+ children: [
226
+ label,
227
+ ":"
228
+ ]
229
+ }
230
+ ),
231
+ /* @__PURE__ */ jsx(
232
+ Box,
233
+ {
234
+ className: css({
235
+ justifySelf: "stretch",
236
+ alignSelf: "start"
237
+ }),
238
+ children: hasMultipleElements ? /* @__PURE__ */ jsx(
239
+ MultiValueDisplay,
240
+ {
241
+ values: elements,
242
+ isExpanded,
243
+ onToggle: handleToggle
244
+ }
245
+ ) : /* @__PURE__ */ jsx(
246
+ Box,
247
+ {
248
+ className: css({
249
+ minHeight: "32px",
250
+ display: "flex",
251
+ alignItems: "center"
252
+ }),
253
+ children: /* @__PURE__ */ jsx(TruncatedValue, { value: elements[0] || "", isExpanded })
254
+ }
255
+ )
256
+ }
257
+ )
258
+ ] });
259
+ }
260
+
261
+ export { MetadataProvider, MetadataValue };
@@ -21,6 +21,10 @@ function inputToSubject(input) {
21
21
  target: input.target
22
22
  };
23
23
  }
24
+ const ViewPadding = {
25
+ x: "22px",
26
+ y: "22px"
27
+ };
24
28
  const _relationshipDetailsLogic = setup({
25
29
  types: {
26
30
  context: {},
@@ -38,13 +42,13 @@ const _relationshipDetailsLogic = setup({
38
42
  const maxZoom = Math.max(xyflow.getZoom(), 1);
39
43
  if (bounds) {
40
44
  const { width, height } = xystore.getState();
41
- const viewport = getViewportForBounds(bounds, width, height, MinZoom, maxZoom, 0.1);
45
+ const viewport = getViewportForBounds(bounds, width, height, MinZoom, maxZoom, ViewPadding);
42
46
  xyflow.setViewport(viewport, duration > 0 ? { duration } : void 0).catch(console.error);
43
47
  } else {
44
48
  xyflow.fitView({
45
49
  minZoom: MinZoom,
46
50
  maxZoom,
47
- padding: 0.1,
51
+ padding: ViewPadding,
48
52
  ...duration > 0 && { duration }
49
53
  }).catch(console.error);
50
54
  }
@@ -1,6 +1,6 @@
1
1
  export declare const ViewPadding: {
2
2
  readonly top: "40px";
3
- readonly bottom: "16px";
4
- readonly left: "16px";
5
- readonly right: "16px";
3
+ readonly bottom: "22px";
4
+ readonly left: "22px";
5
+ readonly right: "22px";
6
6
  };
@@ -1,8 +1,8 @@
1
1
  const ViewPadding = {
2
2
  top: "40px",
3
- bottom: "16px",
4
- left: "16px",
5
- right: "16px"
3
+ bottom: "22px",
4
+ left: "22px",
5
+ right: "22px"
6
6
  };
7
7
 
8
8
  export { ViewPadding };
@@ -1,13 +1,54 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { MantineProvider } from '@mantine/core';
3
+ import { useCallbackRef } from '@mantine/hooks';
3
4
  import { useRef, useCallback } from 'react';
4
5
  import root from 'react-shadow';
5
6
  import { isDefined } from 'remeda';
6
7
  import { FramerMotionConfig } from '../context/FramerMotionConfig.js';
7
8
  import { useId } from '../hooks/useId.js';
8
- import { useColorScheme, useShadowRootStyle, useBundledStyleSheet, DefaultTheme } from './styles.css.js';
9
+ import { useColorScheme, useBundledStyleSheet, DefaultTheme } from './styles.css.js';
9
10
 
10
11
  const Root = root["div"];
12
+ function useShadowRootStyle(instanceId, keepAspectRatio = false) {
13
+ if (keepAspectRatio === false) {
14
+ return `
15
+ :where([data-likec4-instance="${instanceId}"]) {
16
+ display: block;
17
+ box-sizing: border-box;
18
+ border: 0 solid transparent;
19
+ background: transparent;
20
+ padding: 0;
21
+ margin: 0;
22
+ overflow: hidden;
23
+ width: 100%;
24
+ height: 100%;
25
+ min-width: 80px;
26
+ min-height: 80px;
27
+ }
28
+ `.trim();
29
+ }
30
+ const { width, height } = keepAspectRatio;
31
+ const isLandscape = width > height;
32
+ return `
33
+ :where([data-likec4-instance="${instanceId}"]) {
34
+ display: block;
35
+ box-sizing: border-box;
36
+ border: 0 solid transparent;
37
+ background: transparent;
38
+ padding: 0;
39
+ overflow: hidden;
40
+ aspect-ratio: ${Math.ceil(width)} / ${Math.ceil(height)};
41
+ ${isLandscape ? "" : `
42
+ max-width: min(100%, var(--likec4-view-max-width, ${Math.ceil(width)}px));
43
+ margin-left: auto;
44
+ margin-right: auto;`}
45
+ width: ${isLandscape ? "100%" : "auto"};
46
+ height: ${isLandscape ? "auto" : "100%"};
47
+ ${isLandscape ? `min-width: 80px;` : `min-height: 80px;`}
48
+ max-height: min(100%, var(--likec4-view-max-height, ${Math.ceil(height)}px));
49
+ }
50
+ `.trim();
51
+ }
11
52
  function ShadowRoot({
12
53
  children,
13
54
  theme = DefaultTheme,
@@ -23,17 +64,17 @@ function ShadowRoot({
23
64
  const rootRef = useRef(null);
24
65
  const styleSheets = useBundledStyleSheet(injectFontCss, styleNonce);
25
66
  const getRootElement = useCallback(() => rootRef.current ?? void 0, [rootRef]);
26
- let getStyleNonce;
27
- let nonce;
28
- if (isDefined(styleNonce)) {
29
- if (typeof styleNonce === "string") {
30
- nonce = styleNonce;
31
- getStyleNonce = () => styleNonce;
32
- } else if (typeof styleNonce === "function") {
33
- nonce = styleNonce();
34
- getStyleNonce = styleNonce;
67
+ const getStyleNonce = useCallbackRef(() => {
68
+ if (isDefined(styleNonce)) {
69
+ if (typeof styleNonce === "string") {
70
+ return styleNonce;
71
+ } else if (typeof styleNonce === "function") {
72
+ return styleNonce();
73
+ }
35
74
  }
36
- }
75
+ return "";
76
+ });
77
+ let nonce = isDefined(styleNonce) ? getStyleNonce() : void 0;
37
78
  return /* @__PURE__ */ jsxs(Fragment, { children: [
38
79
  /* @__PURE__ */ jsx(
39
80
  "style",
@@ -55,7 +96,7 @@ function ShadowRoot({
55
96
  ...explicitColorScheme && { forceColorScheme: explicitColorScheme },
56
97
  defaultColorScheme: colorScheme,
57
98
  getRootElement,
58
- ...getStyleNonce && { getStyleNonce },
99
+ ...!!nonce && { getStyleNonce },
59
100
  cssVariablesSelector: ".likec4-shadow-root",
60
101
  theme,
61
102
  children: /* @__PURE__ */ jsx(FramerMotionConfig, { children })
@@ -4,7 +4,3 @@ export declare const cssInteractive: string;
4
4
  export declare function useBundledStyleSheet(injectFontCss: boolean, styleNonce?: string | (() => string) | undefined): CSSStyleSheet[];
5
5
  export type ColorScheme = 'light' | 'dark';
6
6
  export declare function useColorScheme(explicit?: ColorScheme): ColorScheme;
7
- export declare function useShadowRootStyle(instanceId: string, keepAspectRatio?: false | {
8
- width: number;
9
- height: number;
10
- }): string;
@@ -95,45 +95,5 @@ function useColorScheme(explicit) {
95
95
  );
96
96
  return explicit ?? computed ?? preferred;
97
97
  }
98
- function useShadowRootStyle(instanceId, keepAspectRatio = false) {
99
- if (keepAspectRatio === false) {
100
- return `
101
- :where([data-likec4-instance="${instanceId}"]) {
102
- display: block;
103
- box-sizing: border-box;
104
- border: 0 solid transparent;
105
- background: transparent;
106
- padding: 0;
107
- margin: 0;
108
- overflow: hidden;
109
- width: 100%;
110
- height: 100%;
111
- min-width: 80px;
112
- min-height: 80px;
113
- }
114
- `.trim();
115
- }
116
- const { width, height } = keepAspectRatio;
117
- const isLandscape = width > height;
118
- return `
119
- :where([data-likec4-instance="${instanceId}"]) {
120
- display: block;
121
- box-sizing: border-box;
122
- border: 0 solid transparent;
123
- background: transparent;
124
- padding: 0;
125
- overflow: hidden;
126
- aspect-ratio: ${Math.ceil(width)} / ${Math.ceil(height)};
127
- ${isLandscape ? "" : `
128
- max-width: min(100%, var(--likec4-view-max-width, ${Math.ceil(width)}px));
129
- margin-left: auto;
130
- margin-right: auto;`}
131
- width: ${isLandscape ? "100%" : "auto"};
132
- height: ${isLandscape ? "auto" : "100%"};
133
- ${isLandscape ? `min-width: 80px;` : `min-height: 80px;`}
134
- max-height: min(100%, var(--likec4-view-max-height, ${Math.ceil(height)}px));
135
- }
136
- `.trim();
137
- }
138
98
 
139
- export { DefaultTheme, useBundledStyleSheet, useColorScheme, useShadowRootStyle };
99
+ export { DefaultTheme, useBundledStyleSheet, useColorScheme };