@likec4/diagram 1.32.0 → 1.32.2
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/README.md +12 -5
- package/bundle/{chunk-BvTQaUYl.js → chunk-DlHyKoeo.js} +236 -210
- package/bundle/custom.js +50 -49
- package/bundle/index.js +144 -121
- package/dist/LikeC4Diagram.js +1 -1
- package/dist/LikeC4Diagram.props.d.ts +14 -3
- package/dist/bundle/LikeC4View.js +16 -15
- package/dist/bundle/ReactLikeC4.js +7 -6
- package/dist/bundle/index.js +1 -1
- package/dist/custom/customNodes.d.ts +5 -0
- package/dist/custom/hooks.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/likec4diagram/DiagramXYFlow.js +3 -3
- package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +5 -5
- package/dist/likec4model/index.d.ts +1 -1
- package/dist/likec4model/useLikeC4Model.d.ts +2 -1
- package/dist/likec4model/useLikeC4Model.js +13 -2
- package/dist/overlays/overlay/Overlay.js +24 -4
- package/dist/search/Search.d.ts +2 -3
- package/dist/search/Search.js +27 -46
- package/dist/search/components/ElementsColumn.js +12 -13
- package/dist/search/components/PickView.js +6 -6
- package/dist/search/components/SearchByTags.js +5 -2
- package/dist/search/components/SearchInput.js +16 -14
- package/dist/search/components/ViewsColum.js +16 -9
- package/dist/search/components/utils.d.ts +3 -2
- package/dist/search/components/utils.js +37 -5
- package/dist/search/hooks.d.ts +2 -8
- package/dist/search/hooks.js +4 -4
- package/dist/state/DiagramActorProvider.js +1 -1
- package/dist/state/diagram-machine.d.ts +216 -8
- package/dist/state/diagram-machine.js +8 -6
- package/package.json +17 -16
- package/panda.buildinfo.json +1 -1
- package/src/LikeC4Diagram.props.ts +14 -3
- package/src/LikeC4Diagram.tsx +1 -1
- package/src/bundle/LikeC4View.tsx +12 -19
- package/src/bundle/ReactLikeC4.tsx +2 -10
- package/src/custom/customNodes.tsx +5 -0
- package/src/custom/hooks.ts +1 -0
- package/src/likec4diagram/DiagramXYFlow.tsx +3 -3
- package/src/likec4model/index.ts +2 -0
- package/src/likec4model/useLikeC4Model.ts +16 -2
- package/src/overlays/overlay/Overlay.tsx +20 -5
- package/src/search/Search.tsx +34 -51
- package/src/search/components/ElementsColumn.tsx +12 -15
- package/src/search/components/PickView.tsx +41 -47
- package/src/search/components/SearchByTags.tsx +5 -2
- package/src/search/components/SearchInput.tsx +17 -14
- package/src/search/components/ViewsColum.tsx +18 -10
- package/src/search/components/utils.ts +41 -4
- package/src/search/hooks.ts +5 -8
- package/src/state/DiagramActorProvider.tsx +2 -1
- package/src/state/diagram-machine.ts +8 -6
|
@@ -3,12 +3,14 @@ import { css } from '@likec4/styles/css';
|
|
|
3
3
|
import { HStack } from '@likec4/styles/jsx';
|
|
4
4
|
import { Button } from '@mantine/core';
|
|
5
5
|
import { IconX } from '@tabler/icons-react';
|
|
6
|
+
import { useRef } from 'react';
|
|
6
7
|
import { useLikeC4Model } from '../../likec4model/useLikeC4Model.js';
|
|
7
8
|
import { useUpdateSearch, useNormalizedSearch } from '../hooks.js';
|
|
8
9
|
import { focusToFirstFoundElement, moveFocusToSearchInput } from './utils.js';
|
|
9
10
|
import { ElementTag } from '../../base/primitives/element/ElementTags.js';
|
|
10
11
|
|
|
11
12
|
function SearchByTags() {
|
|
13
|
+
const ref = useRef(null);
|
|
12
14
|
let tags = useLikeC4Model().tagsSortedByUsage;
|
|
13
15
|
let setSearch = useUpdateSearch();
|
|
14
16
|
let search = useNormalizedSearch();
|
|
@@ -24,6 +26,7 @@ function SearchByTags() {
|
|
|
24
26
|
return /* @__PURE__ */ jsxs(
|
|
25
27
|
HStack,
|
|
26
28
|
{
|
|
29
|
+
ref,
|
|
27
30
|
css: {
|
|
28
31
|
gap: "md",
|
|
29
32
|
paddingLeft: 48,
|
|
@@ -85,7 +88,7 @@ function SearchByTags() {
|
|
|
85
88
|
e.stopPropagation();
|
|
86
89
|
setSearch(`#${tag}`);
|
|
87
90
|
setTimeout(() => {
|
|
88
|
-
focusToFirstFoundElement();
|
|
91
|
+
focusToFirstFoundElement(ref.current);
|
|
89
92
|
}, 350);
|
|
90
93
|
}
|
|
91
94
|
},
|
|
@@ -102,7 +105,7 @@ function SearchByTags() {
|
|
|
102
105
|
onClick: (e) => {
|
|
103
106
|
e.stopPropagation();
|
|
104
107
|
setSearch("");
|
|
105
|
-
moveFocusToSearchInput();
|
|
108
|
+
moveFocusToSearchInput(ref.current);
|
|
106
109
|
},
|
|
107
110
|
rightSection: /* @__PURE__ */ jsx(IconX, { size: 14 }),
|
|
108
111
|
children: "Clear"
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useCombobox, ComboboxOption, Text, Combobox, ComboboxTarget, Input, rem, ComboboxDropdown, ComboboxOptions, ScrollAreaAutosize, ComboboxEmpty } from '@mantine/core';
|
|
3
|
-
import { useFocusWithin, useWindowEvent } from '@mantine/hooks';
|
|
4
|
-
import { usePreviousDistinct } from '@react-hookz/web';
|
|
3
|
+
import { useFocusWithin, useWindowEvent, useMergedRef } from '@mantine/hooks';
|
|
5
4
|
import { IconSearch } from '@tabler/icons-react';
|
|
6
|
-
import { memo } from 'react';
|
|
7
|
-
import { keys
|
|
5
|
+
import { memo, useRef } from 'react';
|
|
6
|
+
import { keys } from 'remeda';
|
|
8
7
|
import { useLikeC4Model } from '../../likec4model/useLikeC4Model.js';
|
|
9
8
|
import { useSearchActor, useSearch } from '../hooks.js';
|
|
10
9
|
import { input } from './styles.css.js';
|
|
@@ -15,11 +14,11 @@ function startingWithKind(search) {
|
|
|
15
14
|
}
|
|
16
15
|
const SEARCH_PREFIXES = ["#", "kind:"];
|
|
17
16
|
const LikeC4SearchInput = memo(() => {
|
|
18
|
-
const
|
|
17
|
+
const searchActorRef = useSearchActor();
|
|
19
18
|
const likec4model = useLikeC4Model();
|
|
19
|
+
const inputRef = useRef(null);
|
|
20
20
|
const { ref, focused } = useFocusWithin();
|
|
21
21
|
const [search, setSearch] = useSearch();
|
|
22
|
-
usePreviousDistinct(search);
|
|
23
22
|
const combobox = useCombobox({
|
|
24
23
|
scrollBehavior: "smooth",
|
|
25
24
|
loop: false
|
|
@@ -29,7 +28,7 @@ const LikeC4SearchInput = memo(() => {
|
|
|
29
28
|
(event) => {
|
|
30
29
|
try {
|
|
31
30
|
if (!focused && (event.key === "Backspace" || event.key.startsWith("Arrow") || event.key.match(/^\p{L}$/u))) {
|
|
32
|
-
moveFocusToSearchInput();
|
|
31
|
+
moveFocusToSearchInput(inputRef.current);
|
|
33
32
|
}
|
|
34
33
|
} catch (e) {
|
|
35
34
|
console.warn(e);
|
|
@@ -51,12 +50,13 @@ const LikeC4SearchInput = memo(() => {
|
|
|
51
50
|
case search.startsWith("#"): {
|
|
52
51
|
const searchTag = search.toLocaleLowerCase().slice(1);
|
|
53
52
|
const alloptions = likec4model.tags.filter((tag) => tag.toLocaleLowerCase().includes(searchTag));
|
|
54
|
-
isExactMatch = only(alloptions)?.toLocaleLowerCase() === searchTag;
|
|
55
53
|
if (alloptions.length === 0) {
|
|
54
|
+
isExactMatch = false;
|
|
56
55
|
options = [
|
|
57
56
|
/* @__PURE__ */ jsx(ComboboxEmpty, { children: "No tags found" }, "empty-tags")
|
|
58
57
|
];
|
|
59
58
|
} else {
|
|
59
|
+
isExactMatch = likec4model.tags.some((tag) => tag.toLocaleLowerCase() === searchTag);
|
|
60
60
|
options = alloptions.map((tag) => /* @__PURE__ */ jsxs(ComboboxOption, { value: `#${tag}`, children: [
|
|
61
61
|
/* @__PURE__ */ jsx(Text, { component: "span", opacity: 0.5, mr: 1, fz: "sm", children: "#" }),
|
|
62
62
|
tag
|
|
@@ -70,13 +70,14 @@ const LikeC4SearchInput = memo(() => {
|
|
|
70
70
|
let alloptions = keys(likec4model.specification.elements);
|
|
71
71
|
if (term) {
|
|
72
72
|
alloptions = alloptions.filter((kind) => kind.toLocaleLowerCase().includes(term));
|
|
73
|
-
isExactMatch = only(alloptions)?.toLocaleLowerCase() === term;
|
|
74
73
|
}
|
|
75
74
|
if (alloptions.length === 0) {
|
|
75
|
+
isExactMatch = false;
|
|
76
76
|
options = [
|
|
77
77
|
/* @__PURE__ */ jsx(ComboboxEmpty, { children: "No kinds found" }, "empty-kinds")
|
|
78
78
|
];
|
|
79
79
|
} else {
|
|
80
|
+
isExactMatch = alloptions.some((kind) => kind.toLocaleLowerCase() === term);
|
|
80
81
|
options = alloptions.map((kind) => /* @__PURE__ */ jsxs(ComboboxOption, { value: `kind:${kind}`, children: [
|
|
81
82
|
/* @__PURE__ */ jsx(Text, { component: "span", opacity: 0.5, mr: 1, fz: "sm", children: "kind:" }),
|
|
82
83
|
kind
|
|
@@ -94,7 +95,7 @@ const LikeC4SearchInput = memo(() => {
|
|
|
94
95
|
if (!SEARCH_PREFIXES.includes(optionValue)) {
|
|
95
96
|
combobox.closeDropdown();
|
|
96
97
|
setTimeout(() => {
|
|
97
|
-
focusToFirstFoundElement();
|
|
98
|
+
focusToFirstFoundElement(inputRef.current);
|
|
98
99
|
}, 350);
|
|
99
100
|
}
|
|
100
101
|
},
|
|
@@ -111,10 +112,11 @@ const LikeC4SearchInput = memo(() => {
|
|
|
111
112
|
/* @__PURE__ */ jsx(ComboboxTarget, { children: /* @__PURE__ */ jsx(
|
|
112
113
|
Input,
|
|
113
114
|
{
|
|
114
|
-
ref,
|
|
115
|
-
id: "likec4searchinput",
|
|
115
|
+
ref: useMergedRef(inputRef, ref),
|
|
116
116
|
placeholder: "Search by title, description or start with # or kind:",
|
|
117
117
|
autoFocus: true,
|
|
118
|
+
"data-autofocus": true,
|
|
119
|
+
"data-likec4-search-input": true,
|
|
118
120
|
tabIndex: 0,
|
|
119
121
|
classNames: {
|
|
120
122
|
input: input
|
|
@@ -129,7 +131,7 @@ const LikeC4SearchInput = memo(() => {
|
|
|
129
131
|
e.stopPropagation();
|
|
130
132
|
const openedWithSearch = searchActorRef.getSnapshot().context.openedWithSearch;
|
|
131
133
|
if (search === "" || search === openedWithSearch) {
|
|
132
|
-
close
|
|
134
|
+
searchActorRef.send({ type: "close" });
|
|
133
135
|
} else {
|
|
134
136
|
setSearch("");
|
|
135
137
|
}
|
|
@@ -197,7 +199,7 @@ const LikeC4SearchInput = memo(() => {
|
|
|
197
199
|
search === "" && combobox.getSelectedOptionIndex() === options.length - 1)) {
|
|
198
200
|
combobox.closeDropdown();
|
|
199
201
|
stopAndPrevent(e);
|
|
200
|
-
focusToFirstFoundElement();
|
|
202
|
+
focusToFirstFoundElement(inputRef.current);
|
|
201
203
|
return;
|
|
202
204
|
}
|
|
203
205
|
}
|
|
@@ -4,18 +4,19 @@ import { Box } from '@likec4/styles/jsx';
|
|
|
4
4
|
import { Stack, VisuallyHidden, UnstyledButton, createScopedKeydownHandler, ThemeIcon, Group, Highlight, Badge } from '@mantine/core';
|
|
5
5
|
import { IconStack2, IconZoomScan } from '@tabler/icons-react';
|
|
6
6
|
import * as m from 'motion/react-m';
|
|
7
|
-
import { memo } from 'react';
|
|
7
|
+
import { memo, useRef } from 'react';
|
|
8
8
|
import { first } from 'remeda';
|
|
9
9
|
import { useCurrentViewId } from '../../hooks/useCurrentViewId.js';
|
|
10
10
|
import { useDiagram } from '../../hooks/useDiagram.js';
|
|
11
11
|
import { useLikeC4Model } from '../../likec4model/useLikeC4Model.js';
|
|
12
|
-
import { useNormalizedSearch } from '../hooks.js';
|
|
12
|
+
import { useNormalizedSearch, useSearchActor } from '../hooks.js';
|
|
13
13
|
import { emptyBoX, buttonsva, focusable } from './_shared.css.js';
|
|
14
|
-
import { moveFocusToSearchInput, centerY } from './utils.js';
|
|
14
|
+
import { moveFocusToSearchInput, queryAllFocusable, centerY } from './utils.js';
|
|
15
15
|
import { viewButton } from './ViewsColumn.css.js';
|
|
16
16
|
|
|
17
17
|
const NothingFound = () => /* @__PURE__ */ jsx(Box, { className: emptyBoX, children: "Nothing found" });
|
|
18
18
|
const ViewsColumn = memo(() => {
|
|
19
|
+
const ref = useRef(null);
|
|
19
20
|
let views = [...useLikeC4Model().views()];
|
|
20
21
|
let search = useNormalizedSearch();
|
|
21
22
|
if (search) {
|
|
@@ -33,15 +34,14 @@ const ViewsColumn = memo(() => {
|
|
|
33
34
|
return /* @__PURE__ */ jsxs(
|
|
34
35
|
Stack,
|
|
35
36
|
{
|
|
37
|
+
ref,
|
|
36
38
|
renderRoot: (props) => /* @__PURE__ */ jsx(m.div, { layout: true, ...props }),
|
|
37
39
|
gap: 8,
|
|
38
40
|
"data-likec4-search-views": true,
|
|
39
41
|
onKeyDown: (e) => {
|
|
40
42
|
if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
|
|
41
43
|
const maxY = e.target.getBoundingClientRect().y;
|
|
42
|
-
const elementButtons =
|
|
43
|
-
`[data-likec4-search-elements] .likec4-focusable`
|
|
44
|
-
)];
|
|
44
|
+
const elementButtons = queryAllFocusable(ref.current, "elements", ".likec4-element-button");
|
|
45
45
|
let elementButton = elementButtons.length > 1 ? elementButtons.find((el, i, all) => centerY(el) > maxY || i === all.length - 1) : null;
|
|
46
46
|
elementButton ??= first(elementButtons);
|
|
47
47
|
if (elementButton) {
|
|
@@ -60,7 +60,7 @@ const ViewsColumn = memo(() => {
|
|
|
60
60
|
tabIndex: -1,
|
|
61
61
|
onFocus: (e) => {
|
|
62
62
|
e.stopPropagation();
|
|
63
|
-
moveFocusToSearchInput();
|
|
63
|
+
moveFocusToSearchInput(ref.current);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
) }),
|
|
@@ -78,9 +78,16 @@ const ViewsColumn = memo(() => {
|
|
|
78
78
|
});
|
|
79
79
|
const btn = buttonsva();
|
|
80
80
|
function ViewButton({ className, view, loop = false, search, ...props }) {
|
|
81
|
+
const searchActorRef = useSearchActor();
|
|
81
82
|
const diagram = useDiagram();
|
|
82
83
|
const currentViewId = useCurrentViewId();
|
|
83
84
|
const isCurrentView = view.id === currentViewId;
|
|
85
|
+
const navigate = () => {
|
|
86
|
+
searchActorRef.send({ type: "close" });
|
|
87
|
+
setTimeout(() => {
|
|
88
|
+
diagram.navigateTo(view.id);
|
|
89
|
+
}, 100);
|
|
90
|
+
};
|
|
84
91
|
return /* @__PURE__ */ jsxs(
|
|
85
92
|
UnstyledButton,
|
|
86
93
|
{
|
|
@@ -90,7 +97,7 @@ function ViewButton({ className, view, loop = false, search, ...props }) {
|
|
|
90
97
|
...isCurrentView && { "data-disabled": true },
|
|
91
98
|
onClick: (e) => {
|
|
92
99
|
e.stopPropagation();
|
|
93
|
-
|
|
100
|
+
navigate();
|
|
94
101
|
},
|
|
95
102
|
onKeyDown: createScopedKeydownHandler({
|
|
96
103
|
siblingSelector: "[data-likec4-view]",
|
|
@@ -101,7 +108,7 @@ function ViewButton({ className, view, loop = false, search, ...props }) {
|
|
|
101
108
|
onKeyDown: (e) => {
|
|
102
109
|
if (e.nativeEvent.code === "Space") {
|
|
103
110
|
e.stopPropagation();
|
|
104
|
-
|
|
111
|
+
navigate();
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
114
|
}),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function stopAndPrevent(e: React.KeyboardEvent | KeyboardEvent): void;
|
|
2
2
|
export declare function centerY(element: HTMLElement): number;
|
|
3
|
-
export declare function moveFocusToSearchInput(): void;
|
|
4
|
-
export declare function focusToFirstFoundElement(): void;
|
|
3
|
+
export declare function moveFocusToSearchInput(from: HTMLElement | null | undefined): void;
|
|
4
|
+
export declare function focusToFirstFoundElement(from: HTMLElement | null | undefined): void;
|
|
5
|
+
export declare function queryAllFocusable(from: HTMLElement | null | undefined, where: 'elements' | 'views', selector?: string): HTMLButtonElement[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isFunction } from 'remeda';
|
|
1
2
|
import { focusable } from './_shared.css.js';
|
|
2
3
|
|
|
3
4
|
function stopAndPrevent(e) {
|
|
@@ -10,17 +11,48 @@ function centerY(element) {
|
|
|
10
11
|
const y = rect.y + Math.floor(rect.height / 2);
|
|
11
12
|
return y;
|
|
12
13
|
}
|
|
13
|
-
function moveFocusToSearchInput() {
|
|
14
|
-
|
|
14
|
+
function moveFocusToSearchInput(from) {
|
|
15
|
+
if (!from) {
|
|
16
|
+
console.error("moveFocusToSearchInput: from is null or undefined");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const root = from.getRootNode();
|
|
20
|
+
if (!isFunction(root.querySelector)) {
|
|
21
|
+
console.error("moveFocusToSearchInput: root.querySelector is not a function");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
let input = root.querySelector("[data-likec4-search-input]");
|
|
15
25
|
if (input) {
|
|
16
26
|
const length = input.value.length;
|
|
17
27
|
input.focus();
|
|
18
28
|
input.setSelectionRange(length, length);
|
|
19
29
|
}
|
|
20
30
|
}
|
|
21
|
-
function focusToFirstFoundElement() {
|
|
22
|
-
|
|
31
|
+
function focusToFirstFoundElement(from) {
|
|
32
|
+
if (!from) {
|
|
33
|
+
console.error("focusToFirstFoundElement: from is null or undefined");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const root = from.getRootNode();
|
|
37
|
+
if (!isFunction(root.querySelector)) {
|
|
38
|
+
console.error("focusToFirstFoundElement: root.querySelector is not a function");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
let firstFoundElement = root.querySelector(`[data-likec4-search] .${focusable}`);
|
|
23
42
|
firstFoundElement?.focus();
|
|
24
43
|
}
|
|
44
|
+
function queryAllFocusable(from, where, selector = `.${focusable}`) {
|
|
45
|
+
if (!from) {
|
|
46
|
+
console.error("queryAllFocusable: from is null or undefined");
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
const root = from.getRootNode();
|
|
50
|
+
if (!isFunction(root.querySelectorAll)) {
|
|
51
|
+
console.error("queryAllFocusable: root.querySelectorAll is not a function");
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const elements = root.querySelectorAll(`[data-likec4-search-${where}] ${selector}`);
|
|
55
|
+
return [...elements];
|
|
56
|
+
}
|
|
25
57
|
|
|
26
|
-
export { centerY, focusToFirstFoundElement, moveFocusToSearchInput, stopAndPrevent };
|
|
58
|
+
export { centerY, focusToFirstFoundElement, moveFocusToSearchInput, queryAllFocusable, stopAndPrevent };
|
package/dist/search/hooks.d.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { SearchActorRef } from './searchActor';
|
|
2
2
|
import { Fqn } from '@likec4/core';
|
|
3
3
|
export declare const SearchActorContext: ({ children, value }: {
|
|
4
|
-
value:
|
|
5
|
-
searchActorRef: SearchActorRef;
|
|
6
|
-
close: (cb?: () => void) => void;
|
|
7
|
-
};
|
|
4
|
+
value: SearchActorRef;
|
|
8
5
|
children: React.ReactNode;
|
|
9
|
-
}) => import("react/jsx-runtime").JSX.Element, useSearchActor: () =>
|
|
10
|
-
searchActorRef: SearchActorRef;
|
|
11
|
-
close: (cb?: () => void) => void;
|
|
12
|
-
};
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element, useSearchActor: () => SearchActorRef;
|
|
13
7
|
export declare function useSearch(): [string, (search: string) => void];
|
|
14
8
|
export declare function useNormalizedSearch(): string;
|
|
15
9
|
export declare function useUpdateSearch(): (search: string) => void;
|
package/dist/search/hooks.js
CHANGED
|
@@ -5,7 +5,7 @@ import { useCallback, useDeferredValue } from 'react';
|
|
|
5
5
|
const [SearchActorContext, useSearchActor] = createSafeContext("SearchActorContext");
|
|
6
6
|
const selectSearchValue = (s) => s.context.searchValue;
|
|
7
7
|
function useSearch() {
|
|
8
|
-
const
|
|
8
|
+
const searchActorRef = useSearchActor();
|
|
9
9
|
const searchValue = useSelector(searchActorRef, selectSearchValue);
|
|
10
10
|
const updateSearch = useCallback((search) => {
|
|
11
11
|
searchActorRef.send({ type: "change.search", search });
|
|
@@ -17,18 +17,18 @@ const selectNormalizedSearchValue = (s) => {
|
|
|
17
17
|
return v.length > 1 ? v : "";
|
|
18
18
|
};
|
|
19
19
|
function useNormalizedSearch() {
|
|
20
|
-
const
|
|
20
|
+
const searchActorRef = useSearchActor();
|
|
21
21
|
return useDeferredValue(useSelector(searchActorRef, selectNormalizedSearchValue));
|
|
22
22
|
}
|
|
23
23
|
function useUpdateSearch() {
|
|
24
|
-
const
|
|
24
|
+
const searchActorRef = useSearchActor();
|
|
25
25
|
return useCallback((search) => {
|
|
26
26
|
searchActorRef.send({ type: "change.search", search });
|
|
27
27
|
}, [searchActorRef]);
|
|
28
28
|
}
|
|
29
29
|
const selectPickViewFor = (s) => s.context.pickViewFor;
|
|
30
30
|
function usePickViewFor() {
|
|
31
|
-
const
|
|
31
|
+
const searchActorRef = useSearchActor();
|
|
32
32
|
return useSelector(searchActorRef, selectPickViewFor);
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -2137,15 +2137,223 @@ declare const _diagramMachine: StateMachine<Context, Events, {
|
|
|
2137
2137
|
};
|
|
2138
2138
|
readonly navigating: {
|
|
2139
2139
|
readonly id: "navigating";
|
|
2140
|
-
readonly entry: readonly ["closeAllOverlays", "closeSearch", "stopSyncLayout", {
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
}) => {
|
|
2146
|
-
viewId: ViewId;
|
|
2140
|
+
readonly entry: readonly ["closeAllOverlays", "closeSearch", "stopSyncLayout", ActionFunction<Context, Events, Events, undefined, Values<{
|
|
2141
|
+
syncManualLayoutActorLogic: {
|
|
2142
|
+
src: "syncManualLayoutActorLogic";
|
|
2143
|
+
logic: SyncLayoutActorLogic;
|
|
2144
|
+
id: "syncLayout";
|
|
2147
2145
|
};
|
|
2148
|
-
|
|
2146
|
+
hotkeyActorLogic: {
|
|
2147
|
+
src: "hotkeyActorLogic";
|
|
2148
|
+
logic: HotkeyActorLogic;
|
|
2149
|
+
id: "hotkey";
|
|
2150
|
+
};
|
|
2151
|
+
overlaysActorLogic: {
|
|
2152
|
+
src: "overlaysActorLogic";
|
|
2153
|
+
logic: OverlaysActorLogic;
|
|
2154
|
+
id: "overlays";
|
|
2155
|
+
};
|
|
2156
|
+
searchActorLogic: {
|
|
2157
|
+
src: "searchActorLogic";
|
|
2158
|
+
logic: SearchActorLogic;
|
|
2159
|
+
id: "search";
|
|
2160
|
+
};
|
|
2161
|
+
}>, Values<{
|
|
2162
|
+
onNodeMouseEnter: {
|
|
2163
|
+
type: "onNodeMouseEnter";
|
|
2164
|
+
params: {
|
|
2165
|
+
node: Types.Node;
|
|
2166
|
+
};
|
|
2167
|
+
};
|
|
2168
|
+
onNodeMouseLeave: {
|
|
2169
|
+
type: "onNodeMouseLeave";
|
|
2170
|
+
params: {
|
|
2171
|
+
node: Types.Node;
|
|
2172
|
+
};
|
|
2173
|
+
};
|
|
2174
|
+
onEdgeMouseEnter: {
|
|
2175
|
+
type: "onEdgeMouseEnter";
|
|
2176
|
+
params: {
|
|
2177
|
+
edge: Types.Edge;
|
|
2178
|
+
};
|
|
2179
|
+
};
|
|
2180
|
+
onEdgeMouseLeave: {
|
|
2181
|
+
type: "onEdgeMouseLeave";
|
|
2182
|
+
params: {
|
|
2183
|
+
edge: Types.Edge;
|
|
2184
|
+
};
|
|
2185
|
+
};
|
|
2186
|
+
"trigger:OnChange": {
|
|
2187
|
+
type: "trigger:OnChange";
|
|
2188
|
+
params: {
|
|
2189
|
+
change: ViewChange;
|
|
2190
|
+
};
|
|
2191
|
+
};
|
|
2192
|
+
"layout.align": {
|
|
2193
|
+
type: "layout.align";
|
|
2194
|
+
params: {
|
|
2195
|
+
mode: AlignmentMode;
|
|
2196
|
+
};
|
|
2197
|
+
};
|
|
2198
|
+
"notations.highlight": {
|
|
2199
|
+
type: "notations.highlight";
|
|
2200
|
+
params: {
|
|
2201
|
+
notation: ElementNotation;
|
|
2202
|
+
kind?: string;
|
|
2203
|
+
};
|
|
2204
|
+
};
|
|
2205
|
+
"tag.highlight": {
|
|
2206
|
+
type: "tag.highlight";
|
|
2207
|
+
params: NonReducibleUnknown;
|
|
2208
|
+
};
|
|
2209
|
+
"xyflow:fitDiagram": {
|
|
2210
|
+
type: "xyflow:fitDiagram";
|
|
2211
|
+
params: {
|
|
2212
|
+
duration?: number;
|
|
2213
|
+
bounds?: BBox;
|
|
2214
|
+
} | undefined;
|
|
2215
|
+
};
|
|
2216
|
+
closeAllOverlays: {
|
|
2217
|
+
type: "closeAllOverlays";
|
|
2218
|
+
params: NonReducibleUnknown;
|
|
2219
|
+
};
|
|
2220
|
+
"trigger:NavigateTo": {
|
|
2221
|
+
type: "trigger:NavigateTo";
|
|
2222
|
+
params: {
|
|
2223
|
+
viewId: ViewId;
|
|
2224
|
+
};
|
|
2225
|
+
};
|
|
2226
|
+
"trigger:OpenSource": {
|
|
2227
|
+
type: "trigger:OpenSource";
|
|
2228
|
+
params: OpenSourceParams;
|
|
2229
|
+
};
|
|
2230
|
+
"assign lastClickedNode": {
|
|
2231
|
+
type: "assign lastClickedNode";
|
|
2232
|
+
params: NonReducibleUnknown;
|
|
2233
|
+
};
|
|
2234
|
+
"open source of focused or last clicked node": {
|
|
2235
|
+
type: "open source of focused or last clicked node";
|
|
2236
|
+
params: NonReducibleUnknown;
|
|
2237
|
+
};
|
|
2238
|
+
"xyflow:fitFocusedBounds": {
|
|
2239
|
+
type: "xyflow:fitFocusedBounds";
|
|
2240
|
+
params: unknown;
|
|
2241
|
+
};
|
|
2242
|
+
"xyflow:setViewportCenter": {
|
|
2243
|
+
type: "xyflow:setViewportCenter";
|
|
2244
|
+
params: {
|
|
2245
|
+
x: number;
|
|
2246
|
+
y: number;
|
|
2247
|
+
};
|
|
2248
|
+
};
|
|
2249
|
+
"xyflow:setViewport": {
|
|
2250
|
+
type: "xyflow:setViewport";
|
|
2251
|
+
params: {
|
|
2252
|
+
viewport: Viewport;
|
|
2253
|
+
duration?: number;
|
|
2254
|
+
};
|
|
2255
|
+
};
|
|
2256
|
+
"xyflow:alignNodeFromToAfterNavigate": {
|
|
2257
|
+
type: "xyflow:alignNodeFromToAfterNavigate";
|
|
2258
|
+
params: {
|
|
2259
|
+
fromNode: NodeId;
|
|
2260
|
+
toPosition: XYPoint;
|
|
2261
|
+
};
|
|
2262
|
+
};
|
|
2263
|
+
"ensure overlays actor state": {
|
|
2264
|
+
type: "ensure overlays actor state";
|
|
2265
|
+
params: NonReducibleUnknown;
|
|
2266
|
+
};
|
|
2267
|
+
"ensure search actor state": {
|
|
2268
|
+
type: "ensure search actor state";
|
|
2269
|
+
params: NonReducibleUnknown;
|
|
2270
|
+
};
|
|
2271
|
+
updateFeatures: {
|
|
2272
|
+
type: "updateFeatures";
|
|
2273
|
+
params: NonReducibleUnknown;
|
|
2274
|
+
};
|
|
2275
|
+
closeSearch: {
|
|
2276
|
+
type: "closeSearch";
|
|
2277
|
+
params: NonReducibleUnknown;
|
|
2278
|
+
};
|
|
2279
|
+
startSyncLayout: {
|
|
2280
|
+
type: "startSyncLayout";
|
|
2281
|
+
params: NonReducibleUnknown;
|
|
2282
|
+
};
|
|
2283
|
+
stopSyncLayout: {
|
|
2284
|
+
type: "stopSyncLayout";
|
|
2285
|
+
params: NonReducibleUnknown;
|
|
2286
|
+
};
|
|
2287
|
+
"focus on nodes and edges": {
|
|
2288
|
+
type: "focus on nodes and edges";
|
|
2289
|
+
params: NonReducibleUnknown;
|
|
2290
|
+
};
|
|
2291
|
+
"undim everything": {
|
|
2292
|
+
type: "undim everything";
|
|
2293
|
+
params: NonReducibleUnknown;
|
|
2294
|
+
};
|
|
2295
|
+
"update active walkthrough": {
|
|
2296
|
+
type: "update active walkthrough";
|
|
2297
|
+
params: NonReducibleUnknown;
|
|
2298
|
+
};
|
|
2299
|
+
}>, Values<{
|
|
2300
|
+
isReady: {
|
|
2301
|
+
type: "isReady";
|
|
2302
|
+
params: unknown;
|
|
2303
|
+
};
|
|
2304
|
+
"enabled: FitView": {
|
|
2305
|
+
type: "enabled: FitView";
|
|
2306
|
+
params: unknown;
|
|
2307
|
+
};
|
|
2308
|
+
"enabled: FocusMode": {
|
|
2309
|
+
type: "enabled: FocusMode";
|
|
2310
|
+
params: unknown;
|
|
2311
|
+
};
|
|
2312
|
+
"enabled: Readonly": {
|
|
2313
|
+
type: "enabled: Readonly";
|
|
2314
|
+
params: unknown;
|
|
2315
|
+
};
|
|
2316
|
+
"enabled: RelationshipDetails": {
|
|
2317
|
+
type: "enabled: RelationshipDetails";
|
|
2318
|
+
params: unknown;
|
|
2319
|
+
};
|
|
2320
|
+
"enabled: Search": {
|
|
2321
|
+
type: "enabled: Search";
|
|
2322
|
+
params: unknown;
|
|
2323
|
+
};
|
|
2324
|
+
"not readonly": {
|
|
2325
|
+
type: "not readonly";
|
|
2326
|
+
params: unknown;
|
|
2327
|
+
};
|
|
2328
|
+
"is dynamic view": {
|
|
2329
|
+
type: "is dynamic view";
|
|
2330
|
+
params: unknown;
|
|
2331
|
+
};
|
|
2332
|
+
"is another view": {
|
|
2333
|
+
type: "is another view";
|
|
2334
|
+
params: unknown;
|
|
2335
|
+
};
|
|
2336
|
+
"click: selected node": {
|
|
2337
|
+
type: "click: selected node";
|
|
2338
|
+
params: unknown;
|
|
2339
|
+
};
|
|
2340
|
+
"click: same node": {
|
|
2341
|
+
type: "click: same node";
|
|
2342
|
+
params: unknown;
|
|
2343
|
+
};
|
|
2344
|
+
"click: focused node": {
|
|
2345
|
+
type: "click: focused node";
|
|
2346
|
+
params: unknown;
|
|
2347
|
+
};
|
|
2348
|
+
"click: node has connections": {
|
|
2349
|
+
type: "click: node has connections";
|
|
2350
|
+
params: unknown;
|
|
2351
|
+
};
|
|
2352
|
+
"click: selected edge": {
|
|
2353
|
+
type: "click: selected edge";
|
|
2354
|
+
params: unknown;
|
|
2355
|
+
};
|
|
2356
|
+
}>, never, EventObject>];
|
|
2149
2357
|
readonly on: {
|
|
2150
2358
|
readonly 'update.view': {
|
|
2151
2359
|
readonly actions: ActionFunction<Context, {
|
|
@@ -819,12 +819,14 @@ const _diagramMachine = setup({
|
|
|
819
819
|
"closeAllOverlays",
|
|
820
820
|
"closeSearch",
|
|
821
821
|
"stopSyncLayout",
|
|
822
|
-
{
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
822
|
+
enqueueActions(({ enqueue, context }) => {
|
|
823
|
+
enqueue({
|
|
824
|
+
type: "trigger:NavigateTo",
|
|
825
|
+
params: {
|
|
826
|
+
viewId: nonNullable(context.lastOnNavigate, "Invalid state, lastOnNavigate is null").toView
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
})
|
|
828
830
|
],
|
|
829
831
|
on: {
|
|
830
832
|
"update.view": {
|