@principal-ai/principal-view-react 0.16.32 → 0.16.34
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.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/subsystem/GraphLayoutCover.d.ts +19 -0
- package/dist/subsystem/GraphLayoutCover.d.ts.map +1 -0
- package/dist/subsystem/GraphLayoutCover.js +42 -0
- package/dist/subsystem/GraphLayoutCover.js.map +1 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts +18 -3
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +185 -34
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/SubsystemFileTree.d.ts +20 -0
- package/dist/subsystem/SubsystemFileTree.d.ts.map +1 -0
- package/dist/subsystem/SubsystemFileTree.js +124 -0
- package/dist/subsystem/SubsystemFileTree.js.map +1 -0
- package/dist/subsystem/model.d.ts +7 -0
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts +2 -0
- package/dist/subsystem/nodes.d.ts.map +1 -1
- package/dist/subsystem/nodes.js +21 -9
- package/dist/subsystem/nodes.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +4 -0
- package/src/stories/SubsystemComponentGraph.stories.tsx +22 -14
- package/src/subsystem/GraphLayoutCover.tsx +69 -0
- package/src/subsystem/SubsystemComponentGraph.tsx +246 -28
- package/src/subsystem/SubsystemFileTree.tsx +158 -0
- package/src/subsystem/model.ts +7 -0
- package/src/subsystem/nodes.tsx +26 -11
package/dist/index.d.ts
CHANGED
|
@@ -51,5 +51,9 @@ export type { JsonValue, GraphifyFileType, GraphifyConfidence, GraphifyNodeType,
|
|
|
51
51
|
export type { GraphifyAnchorResolution, SubsystemGraphifyAnchor, GraphifyMethodInfo, GraphifyPropertyInfo, GraphifyParamInfo, GraphifyCallInfo, GraphifyReferenceInfo, GraphifyImportInfo, GraphifyClassDetail, GraphifyFunctionDetail, GraphifyTypeDetail, GraphifyModuleDetail, GraphifyExternalDetail, GraphifyComponentDetail, GraphifyEdgeRef, } from './graphify';
|
|
52
52
|
export { SubsystemComponentGraph } from './subsystem/SubsystemComponentGraph';
|
|
53
53
|
export type { SubsystemComponentGraphProps } from './subsystem/SubsystemComponentGraph';
|
|
54
|
+
export { SubsystemFileTree } from './subsystem/SubsystemFileTree';
|
|
55
|
+
export type { SubsystemFileTreeProps } from './subsystem/SubsystemFileTree';
|
|
56
|
+
export { GraphLayoutCover } from './subsystem/GraphLayoutCover';
|
|
57
|
+
export type { GraphLayoutCoverProps } from './subsystem/GraphLayoutCover';
|
|
54
58
|
export type { SubsystemComponent, SubsystemComponentEdge, SubsystemGraphDocument, SubsystemComponentKind, SubsystemEdgeMechanism, } from './subsystem/model';
|
|
55
59
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -37,4 +37,6 @@ export { PipelineView, useStateView } from './components/state-view';
|
|
|
37
37
|
export { SessionEventFeed, SessionEventFeedGrouped, } from './components/session-events';
|
|
38
38
|
// Subsystem component graph
|
|
39
39
|
export { SubsystemComponentGraph } from './subsystem/SubsystemComponentGraph';
|
|
40
|
+
export { SubsystemFileTree } from './subsystem/SubsystemFileTree';
|
|
41
|
+
export { GraphLayoutCover } from './subsystem/GraphLayoutCover';
|
|
40
42
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAQ3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAOnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,8BAA8B;AAC9B,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAUtB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,2BAA2B;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,mBAAmB;AACnB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGvG,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,6EAA6E;AAC7E,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,SAAS,EACT,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAsChC,6DAA6D;AAC7D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAmCrE,sEAAsE;AACtE,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAsCrC,4BAA4B;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAQ3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAOnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,8BAA8B;AAC9B,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAUtB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,2BAA2B;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,mBAAmB;AACnB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGvG,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,6EAA6E;AAC7E,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,SAAS,EACT,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAsChC,6DAA6D;AAC7D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAmCrE,sEAAsE;AACtE,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,6BAA6B,CAAC;AAsCrC,4BAA4B;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphLayoutCover — opaque overlay that hides a graph's startup sequence
|
|
3
|
+
* (initial measurement render, layout swap, camera settle animation).
|
|
4
|
+
*
|
|
5
|
+
* Must sit inside a `position: relative` ancestor sized to the canvas; it
|
|
6
|
+
* covers exactly that box. Renders covered from mount and fades out
|
|
7
|
+
* `holdMs` after `revealed` flips true, then stays transparent until the
|
|
8
|
+
* next `revealed → false` reset.
|
|
9
|
+
*/
|
|
10
|
+
export interface GraphLayoutCoverProps {
|
|
11
|
+
/** True once the final layout is ready and the camera has settled. */
|
|
12
|
+
revealed: boolean;
|
|
13
|
+
/** How long to stay fully opaque after `revealed`. @default 650 */
|
|
14
|
+
holdMs?: number;
|
|
15
|
+
/** Label shown while covered. @default 'Laying out graph…' */
|
|
16
|
+
label?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function GraphLayoutCover({ revealed, holdMs, label, }: GraphLayoutCoverProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=GraphLayoutCover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphLayoutCover.d.ts","sourceRoot":"","sources":["../../src/subsystem/GraphLayoutCover.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,MAAY,EACZ,KAA2B,GAC5B,EAAE,qBAAqB,2CA0CvB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* GraphLayoutCover — opaque overlay that hides a graph's startup sequence
|
|
4
|
+
* (initial measurement render, layout swap, camera settle animation).
|
|
5
|
+
*
|
|
6
|
+
* Must sit inside a `position: relative` ancestor sized to the canvas; it
|
|
7
|
+
* covers exactly that box. Renders covered from mount and fades out
|
|
8
|
+
* `holdMs` after `revealed` flips true, then stays transparent until the
|
|
9
|
+
* next `revealed → false` reset.
|
|
10
|
+
*/
|
|
11
|
+
import { useEffect, useState } from 'react';
|
|
12
|
+
import { useTheme } from '@principal-ade/industry-theme';
|
|
13
|
+
export function GraphLayoutCover({ revealed, holdMs = 650, label = 'Laying out graph…', }) {
|
|
14
|
+
const { theme } = useTheme();
|
|
15
|
+
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
16
|
+
const [coverUp, setCoverUp] = useState(true);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!revealed) {
|
|
19
|
+
setCoverUp(true);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const t = setTimeout(() => setCoverUp(false), holdMs);
|
|
23
|
+
return () => clearTimeout(t);
|
|
24
|
+
}, [revealed, holdMs]);
|
|
25
|
+
return (_jsx("div", { style: {
|
|
26
|
+
position: 'absolute',
|
|
27
|
+
inset: 0,
|
|
28
|
+
zIndex: 15,
|
|
29
|
+
background: theme.colors.background,
|
|
30
|
+
display: 'flex',
|
|
31
|
+
alignItems: 'center',
|
|
32
|
+
justifyContent: 'center',
|
|
33
|
+
opacity: coverUp ? 1 : 0,
|
|
34
|
+
transition: 'opacity 200ms ease',
|
|
35
|
+
pointerEvents: 'none',
|
|
36
|
+
}, children: coverUp && (_jsx("span", { style: {
|
|
37
|
+
color: muted,
|
|
38
|
+
fontFamily: theme.fonts.monospace,
|
|
39
|
+
fontSize: theme.fontSizes[0],
|
|
40
|
+
}, children: label })) }));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=GraphLayoutCover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphLayoutCover.js","sourceRoot":"","sources":["../../src/subsystem/GraphLayoutCover.tsx"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAWzD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,QAAQ,EACR,MAAM,GAAG,GAAG,EACZ,KAAK,GAAG,mBAAmB,GACL;IACtB,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC;IACnE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE7C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,EAAE;YACb,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,OAAO;SACR;QACD,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QACtD,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAEvB,OAAO,CACL,cACE,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,EAAE;YACV,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;YACnC,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxB,UAAU,EAAE,oBAAoB;YAChC,aAAa,EAAE,MAAM;SACtB,YAEA,OAAO,IAAI,CACV,eACE,KAAK,EAAE;gBACL,KAAK,EAAE,KAAK;gBACZ,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;gBACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;aAC7B,YAEA,KAAK,GACD,CACR,GACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -24,6 +24,9 @@ export interface SubsystemComponentGraphProps {
|
|
|
24
24
|
maxNodeWidth?: number;
|
|
25
25
|
/** Show edge labels (mechanism names) on the graph. @default true */
|
|
26
26
|
showEdgeLabels?: boolean;
|
|
27
|
+
/** Show the click-to-open file chip under each component name.
|
|
28
|
+
* @default true */
|
|
29
|
+
showFileBadges?: boolean;
|
|
27
30
|
/** Subsystem title displayed in the sidebar. */
|
|
28
31
|
title?: string;
|
|
29
32
|
/** Markdown description rendered in the sidebar. */
|
|
@@ -35,11 +38,23 @@ export interface SubsystemComponentGraphProps {
|
|
|
35
38
|
/** Rendered in the sidebar under the description (e.g. selection inspector). */
|
|
36
39
|
sidebarAfterDescription?: ReactNode;
|
|
37
40
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
+
* Host-injected reader/renderer for the bottom file drawer, keyed by
|
|
42
|
+
* repo-root-relative path. Opening happens on node click (component with a
|
|
43
|
+
* `file`) and sidebar file-tree click. Keeps this package free of fs and
|
|
44
|
+
* code-view dependencies.
|
|
45
|
+
*/
|
|
46
|
+
renderFileViewer?: (file: string) => ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* Legacy component-keyed variant, kept for backward compatibility. When
|
|
49
|
+
* `renderFileViewer` is absent, drawer content resolves via the first
|
|
50
|
+
* component whose `file` matches the opened path.
|
|
41
51
|
*/
|
|
42
52
|
renderFileView?: (component: SubsystemComponent) => ReactNode;
|
|
53
|
+
/**
|
|
54
|
+
* Called when a file in the sidebar file tree is clicked (repo-root-relative
|
|
55
|
+
* path). The tree is derived from the components' `file` values.
|
|
56
|
+
*/
|
|
57
|
+
onFileSelect?: (file: string) => void;
|
|
43
58
|
}
|
|
44
59
|
export declare function SubsystemComponentGraph(props: SubsystemComponentGraphProps): import("react/jsx-runtime").JSX.Element;
|
|
45
60
|
//# sourceMappingURL=SubsystemComponentGraph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubsystemComponentGraph.d.ts","sourceRoot":"","sources":["../../src/subsystem/SubsystemComponentGraph.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAiC,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SubsystemComponentGraph.d.ts","sourceRoot":"","sources":["../../src/subsystem/SubsystemComponentGraph.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAiC,SAAS,EAAE,MAAM,OAAO,CAAC;AAqBtE,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EAExB,MAAM,SAAS,CAAC;AAyBjB,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACtD;kFAC8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;wBACoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,gFAAgF;IAChF,uBAAuB,CAAC,EAAE,SAAS,CAAC;IACpC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IAC/C;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,kBAAkB,KAAK,SAAS,CAAC;IAC9D;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAgxBD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,2CAsC1E"}
|
|
@@ -15,9 +15,12 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
15
15
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
16
16
|
import { ReactFlow, ReactFlowProvider, Background, BackgroundVariant, Controls, useReactFlow, useViewport, applyNodeChanges, } from '@xyflow/react';
|
|
17
17
|
import { useTheme } from '@principal-ade/industry-theme';
|
|
18
|
+
import { X } from 'lucide-react';
|
|
18
19
|
import { IndustryMarkdownSlide } from 'themed-markdown';
|
|
19
20
|
import { buildSubsystemGraph, KIND_COLOR, MECHANISM_COLOR, deriveNameFromSymbol, } from './model';
|
|
20
21
|
import { SubsystemComponentNode, SubsystemEdge, SUBSYSTEM_CALLBACKS } from './nodes';
|
|
22
|
+
import { SubsystemFileTree } from './SubsystemFileTree';
|
|
23
|
+
import { GraphLayoutCover } from './GraphLayoutCover';
|
|
21
24
|
const MECHANISM_DESCRIPTIONS = [
|
|
22
25
|
['imports', 'import statement (code-level dependency)', true],
|
|
23
26
|
['imports_from', 'imported by (reverse dependency)', true],
|
|
@@ -42,7 +45,7 @@ const nodeTypes = {
|
|
|
42
45
|
const edgeTypes = {
|
|
43
46
|
'subsystem-edge': SubsystemEdge,
|
|
44
47
|
};
|
|
45
|
-
function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured, maxNodeWidth, showEdgeLabels, title, description, canvasOverlay, sidebarExtra, sidebarAfterDescription, renderFileView }) {
|
|
48
|
+
function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured, maxNodeWidth, showEdgeLabels, showFileBadges, title, description, canvasOverlay, sidebarExtra, sidebarAfterDescription, renderFileView, renderFileViewer, onFileSelect }) {
|
|
46
49
|
const { theme } = useTheme();
|
|
47
50
|
const { fitView } = useReactFlow();
|
|
48
51
|
const viewport = useViewport();
|
|
@@ -52,10 +55,17 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
52
55
|
});
|
|
53
56
|
const [layoutReady, setLayoutReady] = useState(false);
|
|
54
57
|
const [selected, setSelected] = useState(null);
|
|
58
|
+
// File currently shown in the bottom drawer (repo-root-relative path).
|
|
59
|
+
const [openFile, setOpenFile] = useState(null);
|
|
60
|
+
// Component the pointer is over (null on leave) → transient tree highlight.
|
|
61
|
+
const [hoveredComponentId, setHoveredComponentId] = useState(null);
|
|
55
62
|
// Ref mirror of `selected` so the SUBSYSTEM_CALLBACKS click handler (a
|
|
56
63
|
// closure over the effect deps) can toggle without a stale value.
|
|
57
64
|
const selectedRef = useRef(null);
|
|
58
65
|
selectedRef.current = selected;
|
|
66
|
+
// Ref mirror of `openFile` for the tree-click toggle.
|
|
67
|
+
const openFileRef = useRef(null);
|
|
68
|
+
openFileRef.current = openFile;
|
|
59
69
|
// Pass 1: build with estimated widths so React Flow can measure the DOM.
|
|
60
70
|
// The pane stays hidden until Pass 2 completes.
|
|
61
71
|
useEffect(() => {
|
|
@@ -124,6 +134,7 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
124
134
|
const comp = components.find((c) => c.id === id);
|
|
125
135
|
if (comp) {
|
|
126
136
|
// Clicking the already-selected node unselects it (toggle off).
|
|
137
|
+
// Selection is independent of the file drawer — nodes never open it.
|
|
127
138
|
if (selectedRef.current?.id === comp.id) {
|
|
128
139
|
setSelected(null);
|
|
129
140
|
setSelectedEdgeId(null);
|
|
@@ -136,15 +147,35 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
136
147
|
};
|
|
137
148
|
SUBSYSTEM_CALLBACKS.onEdgeSelect = selectEdge;
|
|
138
149
|
SUBSYSTEM_CALLBACKS.maxNodeWidth = maxNodeWidth;
|
|
150
|
+
SUBSYSTEM_CALLBACKS.onHover = setHoveredComponentId;
|
|
139
151
|
return () => {
|
|
140
152
|
SUBSYSTEM_CALLBACKS.onSelect = undefined;
|
|
141
153
|
SUBSYSTEM_CALLBACKS.onEdgeSelect = undefined;
|
|
142
154
|
SUBSYSTEM_CALLBACKS.maxNodeWidth = undefined;
|
|
155
|
+
SUBSYSTEM_CALLBACKS.onHover = undefined;
|
|
143
156
|
};
|
|
144
157
|
}, [components, onSelect, maxNodeWidth, selectEdge]);
|
|
145
158
|
const { nodes, edges: convertedEdges } = built;
|
|
146
159
|
const xyflowNodesBase = nodes;
|
|
147
160
|
const baseEdges = convertedEdges;
|
|
161
|
+
// While a file is open in the drawer, tag each node with whether its
|
|
162
|
+
// component lives in that file — the node renderer spotlights matches and
|
|
163
|
+
// dims non-matches (mirrors the edge-dimming behavior on selection).
|
|
164
|
+
const dispNodes = useMemo(() => {
|
|
165
|
+
let ns = xyflowNodesBase.map((n) => ({
|
|
166
|
+
...n,
|
|
167
|
+
data: { ...n.data, showFileBadges },
|
|
168
|
+
}));
|
|
169
|
+
if (!openFile)
|
|
170
|
+
return ns;
|
|
171
|
+
return ns.map((n) => {
|
|
172
|
+
const comp = n.data?.component;
|
|
173
|
+
return {
|
|
174
|
+
...n,
|
|
175
|
+
data: { ...n.data, fileMatch: comp?.file === openFile },
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
}, [xyflowNodesBase, openFile, showFileBadges]);
|
|
148
179
|
const baseNodesKey = useMemo(() => nodes.map((n) => n.id).sort().join(','), [nodes]);
|
|
149
180
|
const baseEdgesKey = useMemo(() => convertedEdges.map((e) => e.id).sort().join(','), [convertedEdges]);
|
|
150
181
|
// When an edge is selected, dim every other edge + its label to focus it.
|
|
@@ -172,14 +203,14 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
172
203
|
pendingMeasuredRef.current = true;
|
|
173
204
|
}
|
|
174
205
|
}
|
|
175
|
-
const result = applyNodeChanges(changes,
|
|
206
|
+
const result = applyNodeChanges(changes, dispNodes);
|
|
176
207
|
// After applying changes, check if we should trigger pass 2.
|
|
177
208
|
if (pendingMeasuredRef.current) {
|
|
178
209
|
// Use microtask so the state update from applyNodeChanges commits first.
|
|
179
210
|
queueMicrotask(() => triggerPass2());
|
|
180
211
|
}
|
|
181
212
|
return result;
|
|
182
|
-
}, [
|
|
213
|
+
}, [dispNodes, triggerPass2]);
|
|
183
214
|
const onEdgesChange = useCallback((_changes) => dispEdges, [dispEdges]);
|
|
184
215
|
useEffect(() => {
|
|
185
216
|
const t = setTimeout(() => {
|
|
@@ -187,11 +218,36 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
187
218
|
}, 200);
|
|
188
219
|
return () => clearTimeout(t);
|
|
189
220
|
}, [baseNodesKey, baseEdgesKey, fitView]);
|
|
221
|
+
// When the file drawer opens/closes the canvas resizes — reframe once the
|
|
222
|
+
// height transition settles: onto the matching (spotlit) nodes while a file
|
|
223
|
+
// is open, back to the whole graph when it closes.
|
|
224
|
+
const prevOpenFileRef = useRef(null);
|
|
225
|
+
useEffect(() => {
|
|
226
|
+
const prev = prevOpenFileRef.current;
|
|
227
|
+
prevOpenFileRef.current = openFile;
|
|
228
|
+
if (!layoutReady || prev === openFile)
|
|
229
|
+
return;
|
|
230
|
+
const t = setTimeout(() => {
|
|
231
|
+
if (openFile) {
|
|
232
|
+
const ids = xyflowNodesBase
|
|
233
|
+
.filter((n) => n.data?.component?.file === openFile)
|
|
234
|
+
.map((n) => ({ id: n.id }));
|
|
235
|
+
if (ids.length > 0) {
|
|
236
|
+
fitView({ nodes: ids, padding: 0.35, minZoom: 0.05, maxZoom: 2, duration: 250 });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
fitView({ padding: 0.1, includeHiddenNodes: false, minZoom: 0.05, maxZoom: 2, duration: 250 });
|
|
241
|
+
}
|
|
242
|
+
}, 230);
|
|
243
|
+
return () => clearTimeout(t);
|
|
244
|
+
}, [openFile, layoutReady, xyflowNodesBase, fitView]);
|
|
190
245
|
const onNodeClick = useCallback((_e, node) => {
|
|
191
246
|
const comp = node.data?.component;
|
|
192
247
|
setSelectedEdgeId(null);
|
|
193
248
|
if (node.type === 'subsystem-component' && comp) {
|
|
194
249
|
// Clicking the already-selected node unselects it (toggle off).
|
|
250
|
+
// Selection is independent of the file drawer — nodes never open it.
|
|
195
251
|
if (selected?.id === comp.id) {
|
|
196
252
|
setSelected(null);
|
|
197
253
|
return;
|
|
@@ -209,6 +265,16 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
209
265
|
setSelected(null);
|
|
210
266
|
setSelectedEdgeId(null);
|
|
211
267
|
}, []);
|
|
268
|
+
// Sidebar file-tree click → toggle in the bottom drawer (+ host hook only
|
|
269
|
+
// when opening, so hosts don't see close events).
|
|
270
|
+
const onTreeSelectFile = useCallback((file) => {
|
|
271
|
+
if (openFileRef.current === file) {
|
|
272
|
+
setOpenFile(null);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
setOpenFile(file);
|
|
276
|
+
onFileSelect?.(file);
|
|
277
|
+
}, [onFileSelect]);
|
|
212
278
|
// Edge label data for the overlay (rendered OUTSIDE ReactFlow so the pane
|
|
213
279
|
// doesn't intercept pointer events). Uses ELK-computed label midpoints from
|
|
214
280
|
// the actual edge path (not node-center approximations).
|
|
@@ -228,30 +294,58 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
228
294
|
return new Set(edgeLabels.map((l) => l.mechanism));
|
|
229
295
|
}, [edgeLabels]);
|
|
230
296
|
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
297
|
+
// Unique source files across components → sidebar file tree.
|
|
298
|
+
const files = useMemo(() => Array.from(new Set(components.map((c) => c.file).filter(Boolean))).sort(), [components]);
|
|
299
|
+
// The hovered node's file (null when not hovering / file-less component).
|
|
300
|
+
const hoveredFile = useMemo(() => {
|
|
301
|
+
if (!hoveredComponentId)
|
|
302
|
+
return null;
|
|
303
|
+
return components.find((c) => c.id === hoveredComponentId)?.file ?? null;
|
|
304
|
+
}, [components, hoveredComponentId]);
|
|
305
|
+
// Drawer content renderer: prefer the path-keyed viewer; fall back to the
|
|
306
|
+
// legacy component-keyed one via a file → first-component lookup.
|
|
307
|
+
const fileViewer = useMemo(() => {
|
|
308
|
+
if (renderFileViewer)
|
|
309
|
+
return renderFileViewer;
|
|
310
|
+
if (renderFileView) {
|
|
311
|
+
const byFile = new Map(components.filter((c) => c.file).map((c) => [c.file, c]));
|
|
312
|
+
return (file) => {
|
|
313
|
+
const comp = byFile.get(file);
|
|
314
|
+
return comp ? renderFileView(comp) : null;
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
return undefined;
|
|
318
|
+
}, [renderFileViewer, renderFileView, components]);
|
|
319
|
+
return (_jsxs("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'row' }, children: [(title || description || usedMechanisms.size > 0 || sidebarExtra || sidebarAfterDescription || files.length > 0) && (_jsxs("div", { style: {
|
|
320
|
+
width: 340,
|
|
321
|
+
minWidth: 340,
|
|
234
322
|
borderRight: `1px solid ${theme.colors.border}`,
|
|
235
323
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
236
|
-
padding: '16px',
|
|
237
|
-
overflowY: 'auto',
|
|
238
324
|
display: 'flex',
|
|
239
325
|
flexDirection: 'column',
|
|
240
|
-
|
|
241
|
-
}, children: [
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
326
|
+
overflow: 'hidden',
|
|
327
|
+
}, children: [_jsxs("div", { style: {
|
|
328
|
+
flex: 1,
|
|
329
|
+
minHeight: 0,
|
|
330
|
+
overflowY: 'auto',
|
|
331
|
+
padding: '16px',
|
|
332
|
+
display: 'flex',
|
|
333
|
+
flexDirection: 'column',
|
|
334
|
+
gap: 12,
|
|
335
|
+
}, children: [sidebarExtra, title && (_jsx("h2", { style: {
|
|
336
|
+
margin: 0,
|
|
337
|
+
fontSize: theme.fontSizes[2],
|
|
338
|
+
fontWeight: 600,
|
|
339
|
+
color: theme.colors.text,
|
|
340
|
+
fontFamily: theme.fonts.heading,
|
|
341
|
+
}, children: title })), description && (_jsx("div", { style: { fontSize: theme.fontSizes[0], lineHeight: 1.5 }, children: _jsx(IndustryMarkdownSlide, { content: description, slideIdPrefix: "subsystem-desc", slideIndex: 0, isVisible: true, theme: theme, disableScroll: true, fontSizeScale: 0.9, enableKeyboardScrolling: false, autoFocusOnVisible: false }) })), sidebarAfterDescription, usedMechanisms.size > 0 && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: [_jsx("span", { style: { fontSize: theme.fontSizes[0] * 0.8, fontFamily: theme.fonts.monospace, textTransform: 'uppercase', color: muted, fontWeight: 600 }, children: "Edge Legend" }), MECHANISM_DESCRIPTIONS.filter(([m]) => usedMechanisms.has(m)).map(([mechanism, desc, verifiable]) => (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 6, fontSize: theme.fontSizes[0] }, children: [_jsx("span", { style: {
|
|
342
|
+
width: 8,
|
|
343
|
+
height: 8,
|
|
344
|
+
borderRadius: verifiable ? '50%' : '30% 70% 70% 30% / 30% 30% 70% 70%',
|
|
345
|
+
background: MECHANISM_COLOR[mechanism],
|
|
346
|
+
border: verifiable ? 'none' : `1px dashed ${MECHANISM_COLOR[mechanism]}`,
|
|
347
|
+
flexShrink: 0,
|
|
348
|
+
} }), _jsx("span", { style: { fontFamily: theme.fonts.monospace, color: MECHANISM_COLOR[mechanism], fontWeight: 500 }, children: mechanism }), _jsx("span", { style: { color: muted }, children: desc })] }, mechanism)))] }))] }), files.length > 0 && (_jsx(SubsystemFileTree, { files: files, selectedFile: selected?.file ?? openFile, hoveredFile: hoveredFile, onSelectFile: onTreeSelectFile }))] })), _jsxs("div", { style: { flex: 1, position: 'relative', display: 'flex', flexDirection: 'column', minHeight: 0 }, children: [showEdgeLabels !== false && (_jsx("div", { style: {
|
|
255
349
|
position: 'absolute',
|
|
256
350
|
inset: 0,
|
|
257
351
|
overflow: 'hidden',
|
|
@@ -283,17 +377,18 @@ function Inner({ components, edges, onSelect, onEdgeSelect, measured: _measured,
|
|
|
283
377
|
opacity: lbl.dimmed ? 0.15 : 1,
|
|
284
378
|
whiteSpace: 'nowrap',
|
|
285
379
|
}, children: lbl.mechanism }, lbl.id));
|
|
286
|
-
}) })), _jsxs(ReactFlow, { nodes:
|
|
380
|
+
}) })), _jsxs(ReactFlow, { nodes: dispNodes, edges: dispEdges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, minZoom: 0.05, maxZoom: 4, onNodeClick: onNodeClick, onEdgeClick: onEdgeClick, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, proOptions: { hideAttribution: true }, nodesDraggable: false, elementsSelectable: true, selectNodesOnDrag: false, nodesConnectable: false, edgesReconnectable: false, onPaneClick: onPaneClick, panOnDrag: true, panOnScroll: true, zoomOnScroll: false, zoomOnPinch: true, zoomOnDoubleClick: false, style: {
|
|
287
381
|
width: '100%',
|
|
288
382
|
height: '100%',
|
|
289
383
|
flex: 1,
|
|
290
384
|
minHeight: 0,
|
|
291
385
|
background: theme.colors.background,
|
|
292
|
-
}, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 16, size: 1 }), _jsx(Controls, { showZoom: true, showFitView: true, showInteractive: true })] }, `${baseNodesKey}-${baseEdgesKey}`), selected && _jsx(ComponentDetail, { component: selected,
|
|
386
|
+
}, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 16, size: 1 }), _jsx(Controls, { showZoom: true, showFitView: true, showInteractive: true })] }, `${baseNodesKey}-${baseEdgesKey}`), selected && _jsx(ComponentDetail, { component: selected }), _jsx(FileDrawer, { file: openFile, onClose: () => setOpenFile(null), children: fileViewer && openFile ? fileViewer(openFile) : null }), _jsx(GraphLayoutCover, { revealed: layoutReady }), canvasOverlay] })] }));
|
|
293
387
|
}
|
|
294
388
|
/** Detail panel for the selected component — the verifiable identity + sources
|
|
295
|
-
* moved off the canvas so nodes stay minimal.
|
|
296
|
-
|
|
389
|
+
* moved off the canvas so nodes stay minimal. File content lives in the
|
|
390
|
+
* bottom FileDrawer, not here. */
|
|
391
|
+
function ComponentDetail({ component }) {
|
|
297
392
|
const { theme } = useTheme();
|
|
298
393
|
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
299
394
|
const color = KIND_COLOR[component.kind] ?? '#888';
|
|
@@ -330,13 +425,69 @@ function ComponentDetail({ component, renderFileView }) {
|
|
|
330
425
|
fontFamily: theme.fonts.monospace,
|
|
331
426
|
textTransform: 'uppercase',
|
|
332
427
|
fontSize: theme.fontSizes[0] * 0.8,
|
|
333
|
-
}, children: k }), _jsx("span", { style: { color: theme.colors.text, fontFamily: theme.fonts.monospace }, children: v })] }, k))), component.detail && _jsx(GraphifyDetailSections, { detail: component.detail })
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
428
|
+
}, children: k }), _jsx("span", { style: { color: theme.colors.text, fontFamily: theme.fonts.monospace }, children: v })] }, k))), component.detail && _jsx(GraphifyDetailSections, { detail: component.detail })] }));
|
|
429
|
+
}
|
|
430
|
+
/** Bottom panel that slides up from the bottom of the graph area to show a
|
|
431
|
+
* file's contents — opened by node clicks and sidebar file-tree clicks
|
|
432
|
+
* alike. Sits in normal flow (canvas shrinks while open, nothing covered)
|
|
433
|
+
* and animates via height; stays mounted so open/close animates. */
|
|
434
|
+
function FileDrawer({ file, onClose, children, }) {
|
|
435
|
+
const { theme } = useTheme();
|
|
436
|
+
const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
|
|
437
|
+
const open = file !== null;
|
|
438
|
+
useEffect(() => {
|
|
439
|
+
if (!open)
|
|
440
|
+
return;
|
|
441
|
+
const onKey = (e) => {
|
|
442
|
+
if (e.key === 'Escape')
|
|
443
|
+
onClose();
|
|
444
|
+
};
|
|
445
|
+
window.addEventListener('keydown', onKey);
|
|
446
|
+
return () => window.removeEventListener('keydown', onKey);
|
|
447
|
+
}, [open, onClose]);
|
|
448
|
+
return (_jsxs("div", { style: {
|
|
449
|
+
position: 'relative',
|
|
450
|
+
// Above the absolute edge-label overlay (zIndex 5), which spans the
|
|
451
|
+
// whole graph-area container including this panel's slice.
|
|
452
|
+
zIndex: 6,
|
|
453
|
+
flexShrink: 0,
|
|
454
|
+
height: open ? '45%' : 0,
|
|
455
|
+
minHeight: 0,
|
|
456
|
+
overflow: 'hidden',
|
|
457
|
+
display: 'flex',
|
|
458
|
+
flexDirection: 'column',
|
|
459
|
+
background: theme.colors.background,
|
|
460
|
+
borderTop: open ? `1px solid ${theme.colors.border}` : 'none',
|
|
461
|
+
transition: 'height 200ms ease',
|
|
462
|
+
}, children: [_jsxs("div", { style: {
|
|
463
|
+
display: 'flex',
|
|
464
|
+
alignItems: 'center',
|
|
465
|
+
gap: 8,
|
|
466
|
+
padding: '6px 10px',
|
|
467
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
468
|
+
flexShrink: 0,
|
|
469
|
+
}, children: [_jsx("span", { title: file ?? undefined, style: {
|
|
470
|
+
flex: 1,
|
|
471
|
+
minWidth: 0,
|
|
472
|
+
overflow: 'hidden',
|
|
473
|
+
textOverflow: 'ellipsis',
|
|
474
|
+
whiteSpace: 'nowrap',
|
|
475
|
+
fontFamily: theme.fonts.monospace,
|
|
476
|
+
fontSize: theme.fontSizes[0],
|
|
477
|
+
color: muted,
|
|
478
|
+
}, children: file }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close file", style: {
|
|
479
|
+
display: 'inline-flex',
|
|
480
|
+
alignItems: 'center',
|
|
481
|
+
justifyContent: 'center',
|
|
482
|
+
width: 22,
|
|
483
|
+
height: 22,
|
|
484
|
+
padding: 0,
|
|
485
|
+
border: 'none',
|
|
486
|
+
borderRadius: 4,
|
|
487
|
+
background: 'transparent',
|
|
488
|
+
color: theme.colors.text,
|
|
489
|
+
cursor: 'pointer',
|
|
490
|
+
}, children: _jsx(X, { size: 14 }) })] }), _jsx("div", { style: { flex: 1, minHeight: 0, overflow: 'auto' }, children: children })] }));
|
|
340
491
|
}
|
|
341
492
|
/** Renders the graphify drill-down payload for a component. */
|
|
342
493
|
function GraphifyDetailSections({ detail }) {
|