@likec4/diagram 1.17.1 → 1.19.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.
- package/LICENSE +1 -1
- package/dist/LikeC4CustomColors.d.ts +7 -0
- package/dist/LikeC4CustomColors.js +30 -0
- package/dist/LikeC4Diagram.css.d.ts +5 -0
- package/dist/LikeC4Diagram.css.js +13 -0
- package/dist/LikeC4Diagram.d.ts +6 -0
- package/dist/LikeC4Diagram.js +194 -0
- package/dist/LikeC4Diagram.props.d.ts +166 -0
- package/dist/LikeC4ModelProvider.d.ts +9 -0
- package/dist/LikeC4ModelProvider.js +12 -0
- package/dist/LikeC4Search.css.d.ts +1 -0
- package/dist/LikeC4Search.css.js +5 -0
- package/dist/LikeC4Search.d.ts +2 -0
- package/dist/LikeC4Search.js +96 -0
- package/dist/StaticLikeC4Diagram.d.ts +3 -0
- package/dist/StaticLikeC4Diagram.js +41 -0
- package/dist/_virtual/_commonjsHelpers.js +6 -0
- package/dist/controls/Text.d.ts +2 -0
- package/dist/controls/Text.js +7 -0
- package/dist/controls/action-button-bar/ActionButtonBar.css.d.ts +1 -0
- package/dist/controls/action-button-bar/ActionButtonBar.css.js +5 -0
- package/dist/controls/action-button-bar/ActionButtonBar.d.ts +9 -0
- package/dist/controls/action-button-bar/ActionButtonBar.js +100 -0
- package/dist/controls/action-button-bar/useActionButtonBarCtx.d.ts +10 -0
- package/dist/controls/action-button-bar/useActionButtonBarCtx.js +9 -0
- package/dist/controls/action-buttons/ActionButton.css.d.ts +1 -0
- package/dist/controls/action-buttons/ActionButton.css.js +5 -0
- package/dist/controls/action-buttons/ActionButton.d.ts +9 -0
- package/dist/controls/action-buttons/ActionButton.js +66 -0
- package/dist/controls/action-buttons/ActionButtons.d.ts +12 -0
- package/dist/controls/action-buttons/ActionButtons.js +99 -0
- package/dist/globals.css.d.ts +1 -0
- package/dist/globals.css.js +92 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/useDiagramState.d.ts +6 -0
- package/dist/hooks/useDiagramState.js +27 -0
- package/dist/hooks/useMantinePortalProps.d.ts +9 -0
- package/dist/hooks/useMantinePortalProps.js +9 -0
- package/dist/hooks/useSetState.d.ts +2 -0
- package/dist/hooks/useSetState.js +19 -0
- package/dist/hooks/useUpdateEffect.d.ts +4 -0
- package/dist/hooks/useUpdateEffect.js +32 -0
- package/dist/hooks/useXYFlow.d.ts +270 -0
- package/dist/hooks/useXYFlow.js +20 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +25 -0
- package/dist/likec4model/LikeC4ModelContext.d.ts +3 -0
- package/dist/likec4model/LikeC4ModelContext.js +5 -0
- package/dist/likec4model/index.d.ts +2 -0
- package/dist/likec4model/useLikeC4ElementsTree.d.ts +12 -0
- package/dist/likec4model/useLikeC4ElementsTree.js +25 -0
- package/dist/likec4model/useLikeC4Model.d.ts +20 -0
- package/dist/likec4model/useLikeC4Model.js +55 -0
- package/dist/overlays/OverlayContext.d.ts +10 -0
- package/dist/overlays/OverlayContext.js +9 -0
- package/dist/overlays/Overlays.css.d.ts +3 -0
- package/dist/overlays/Overlays.css.js +7 -0
- package/dist/overlays/Overlays.d.ts +2 -0
- package/dist/overlays/Overlays.js +137 -0
- package/dist/overlays/edge-details/EdgeDetailsXYFlow.d.ts +5 -0
- package/dist/overlays/edge-details/EdgeDetailsXYFlow.js +185 -0
- package/dist/overlays/edge-details/SelectEdge.css.d.ts +7 -0
- package/dist/overlays/edge-details/SelectEdge.css.js +17 -0
- package/dist/overlays/edge-details/SelectEdge.d.ts +5 -0
- package/dist/overlays/edge-details/SelectEdge.js +129 -0
- package/dist/overlays/edge-details/_types.d.ts +14 -0
- package/dist/overlays/edge-details/use-layouted-edge-details.d.ts +21 -0
- package/dist/overlays/edge-details/use-layouted-edge-details.js +270 -0
- package/dist/overlays/edge-details/xyflow/CompoundNode.d.ts +5 -0
- package/dist/overlays/edge-details/xyflow/CompoundNode.js +76 -0
- package/dist/overlays/edge-details/xyflow/ElementNode.d.ts +5 -0
- package/dist/overlays/edge-details/xyflow/ElementNode.js +159 -0
- package/dist/overlays/edge-details/xyflow/RelationshipEdge.d.ts +3 -0
- package/dist/overlays/edge-details/xyflow/RelationshipEdge.js +84 -0
- package/dist/overlays/edge-details/xyflow/styles.css.d.ts +9 -0
- package/dist/overlays/edge-details/xyflow/styles.css.js +21 -0
- package/dist/overlays/element-details/ElementDetailsCard.css.d.ts +16 -0
- package/dist/overlays/element-details/ElementDetailsCard.css.js +33 -0
- package/dist/overlays/element-details/ElementDetailsCard.d.ts +7 -0
- package/dist/overlays/element-details/ElementDetailsCard.js +484 -0
- package/dist/overlays/element-details/TabPanelDeployments.css.d.ts +4 -0
- package/dist/overlays/element-details/TabPanelDeployments.css.js +11 -0
- package/dist/overlays/element-details/TabPanelDeployments.d.ts +7 -0
- package/dist/overlays/element-details/TabPanelDeployments.js +173 -0
- package/dist/overlays/element-details/TabPanelRelationships.css.d.ts +5 -0
- package/dist/overlays/element-details/TabPanelRelationships.css.js +11 -0
- package/dist/overlays/element-details/TabPanelRelationships.d.ts +8 -0
- package/dist/overlays/element-details/TabPanelRelationships.js +157 -0
- package/dist/overlays/element-details/TabPanelStructure.css.d.ts +2 -0
- package/dist/overlays/element-details/TabPanelStructure.css.js +7 -0
- package/dist/overlays/element-details/TabPanelStructure.d.ts +25 -0
- package/dist/overlays/element-details/TabPanelStructure.js +91 -0
- package/dist/overlays/index.d.ts +1 -0
- package/dist/overlays/relationships-of/RelationshipsOverlay.d.ts +5 -0
- package/dist/overlays/relationships-of/RelationshipsOverlay.js +193 -0
- package/dist/overlays/relationships-of/RelationshipsXYFlow.d.ts +19 -0
- package/dist/overlays/relationships-of/RelationshipsXYFlow.js +290 -0
- package/dist/overlays/relationships-of/SelectElement.css.d.ts +2 -0
- package/dist/overlays/relationships-of/SelectElement.css.js +7 -0
- package/dist/overlays/relationships-of/SelectElement.d.ts +7 -0
- package/dist/overlays/relationships-of/SelectElement.js +126 -0
- package/dist/overlays/relationships-of/_types.d.ts +28 -0
- package/dist/overlays/relationships-of/use-layouted-relationships.d.ts +22 -0
- package/dist/overlays/relationships-of/use-layouted-relationships.js +496 -0
- package/dist/overlays/relationships-of/xyflow/CompoundNode.d.ts +6 -0
- package/dist/overlays/relationships-of/xyflow/CompoundNode.js +120 -0
- package/dist/overlays/relationships-of/xyflow/ElementNode.d.ts +6 -0
- package/dist/overlays/relationships-of/xyflow/ElementNode.js +194 -0
- package/dist/overlays/relationships-of/xyflow/EmptyNode.d.ts +5 -0
- package/dist/overlays/relationships-of/xyflow/EmptyNode.js +18 -0
- package/dist/overlays/relationships-of/xyflow/RelationshipEdge.d.ts +3 -0
- package/dist/overlays/relationships-of/xyflow/RelationshipEdge.js +123 -0
- package/dist/overlays/relationships-of/xyflow/styles.css.d.ts +14 -0
- package/dist/overlays/relationships-of/xyflow/styles.css.js +24 -0
- package/dist/overlays/shared/xyflow/RelationshipEdge.css.d.ts +4 -0
- package/dist/overlays/shared/xyflow/RelationshipEdge.css.js +12 -0
- package/dist/overlays/shared/xyflow/_types.d.ts +77 -0
- package/dist/state/DiagramContext.d.ts +1609 -0
- package/dist/state/DiagramContext.js +101 -0
- package/dist/state/aligners.d.ts +42 -0
- package/dist/state/aligners.js +349 -0
- package/dist/state/diagram-to-xyflow.d.ts +11 -0
- package/dist/state/diagram-to-xyflow.js +113 -0
- package/dist/state/diagramStore.d.ts +1705 -0
- package/dist/state/diagramStore.js +808 -0
- package/dist/state/diagramStore.layout.d.ts +4 -0
- package/dist/state/diagramStore.layout.js +56 -0
- package/dist/style.css +1 -0
- package/dist/theme-vars.css.d.ts +72 -0
- package/dist/theme-vars.css.js +6 -0
- package/dist/theme-vars.css.ts.vanilla.css.js +1 -0
- package/dist/theme-vars.d.ts +3 -0
- package/dist/theme-vars.js +5 -0
- package/dist/ui/DiagramTitlePanel.css.d.ts +4 -0
- package/dist/ui/DiagramTitlePanel.css.js +11 -0
- package/dist/ui/DiagramTitlePanel.d.ts +1 -0
- package/dist/ui/DiagramTitlePanel.js +159 -0
- package/dist/ui/DynamicViewWalkthrough.css.d.ts +4 -0
- package/dist/ui/DynamicViewWalkthrough.css.js +11 -0
- package/dist/ui/DynamicViewWalkthrough.d.ts +1 -0
- package/dist/ui/DynamicViewWalkthrough.js +156 -0
- package/dist/ui/EnsureMantine.d.ts +7 -0
- package/dist/ui/EnsureMantine.js +14 -0
- package/dist/ui/FramerMotionConfig.d.ts +2 -0
- package/dist/ui/FramerMotionConfig.js +14 -0
- package/dist/ui/Link.d.ts +4 -0
- package/dist/ui/Link.js +36 -0
- package/dist/ui/notation/NotationPanel.css.d.ts +6 -0
- package/dist/ui/notation/NotationPanel.css.js +16 -0
- package/dist/ui/notation/NotationPanel.d.ts +1 -0
- package/dist/ui/notation/NotationPanel.js +250 -0
- package/dist/ui/notation/index.d.ts +1 -0
- package/dist/ui/top-left/ChangeAutoLayoutButton.d.ts +2 -0
- package/dist/ui/top-left/ChangeAutoLayoutButton.js +159 -0
- package/dist/ui/top-left/ManualLayoutToolsButton.d.ts +2 -0
- package/dist/ui/top-left/ManualLayoutToolsButton.js +137 -0
- package/dist/ui/top-left/TopLeftPanel.d.ts +4 -0
- package/dist/ui/top-left/TopLeftPanel.js +211 -0
- package/dist/ui/top-left/_shared.d.ts +7 -0
- package/dist/ui/top-left/_shared.js +22 -0
- package/dist/ui/top-left/styles.css.d.ts +8 -0
- package/dist/ui/top-left/styles.css.js +17 -0
- package/dist/utils/types.d.ts +8 -0
- package/dist/utils/vector.d.ts +24 -0
- package/dist/utils/vector.js +55 -0
- package/dist/xyflow/EdgeMarkers.d.ts +12 -0
- package/dist/xyflow/EdgeMarkers.js +192 -0
- package/dist/xyflow/FitviewOnDiagramChange.d.ts +4 -0
- package/dist/xyflow/FitviewOnDiagramChange.js +72 -0
- package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +1 -0
- package/dist/xyflow/SelectEdgesOnNodeFocus.js +96 -0
- package/dist/xyflow/XYFlow.d.ts +8 -0
- package/dist/xyflow/XYFlow.js +145 -0
- package/dist/xyflow/XYFlowBackground.d.ts +10 -0
- package/dist/xyflow/XYFlowBackground.js +25 -0
- package/dist/xyflow/XYFlowInner.d.ts +8 -0
- package/dist/xyflow/XYFlowInner.js +41 -0
- package/dist/xyflow/const.d.ts +7 -0
- package/dist/xyflow/const.js +12 -0
- package/dist/xyflow/edges/EdgeLabel.d.ts +7 -0
- package/dist/xyflow/edges/EdgeLabel.js +160 -0
- package/dist/xyflow/edges/RelationshipEdge.d.ts +6 -0
- package/dist/xyflow/edges/RelationshipEdge.js +443 -0
- package/dist/xyflow/edges/RelationshipsDropdownMenu.css.d.ts +4 -0
- package/dist/xyflow/edges/RelationshipsDropdownMenu.css.js +11 -0
- package/dist/xyflow/edges/RelationshipsDropdownMenu.d.ts +13 -0
- package/dist/xyflow/edges/RelationshipsDropdownMenu.js +211 -0
- package/dist/xyflow/edges/edges.css.d.ts +17 -0
- package/dist/xyflow/edges/edges.css.js +37 -0
- package/dist/xyflow/edges/utils.d.ts +16 -0
- package/dist/xyflow/edges/utils.js +24 -0
- package/dist/xyflow/nodes/AnimateVariants.d.ts +1313 -0
- package/dist/xyflow/nodes/AnimateVariants.js +123 -0
- package/dist/xyflow/nodes/Node.css.d.ts +3 -0
- package/dist/xyflow/nodes/Node.css.js +9 -0
- package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +14 -0
- package/dist/xyflow/nodes/compound/CompoundNode.css.js +27 -0
- package/dist/xyflow/nodes/compound/CompoundNode.d.ts +6 -0
- package/dist/xyflow/nodes/compound/CompoundNode.js +216 -0
- package/dist/xyflow/nodes/compound/index.d.ts +1 -0
- package/dist/xyflow/nodes/element/ElementLink.css.d.ts +3 -0
- package/dist/xyflow/nodes/element/ElementLink.d.ts +6 -0
- package/dist/xyflow/nodes/element/ElementNode.d.ts +6 -0
- package/dist/xyflow/nodes/element/ElementNode.js +190 -0
- package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +17 -0
- package/dist/xyflow/nodes/element/ElementShapeSvg.js +175 -0
- package/dist/xyflow/nodes/element/element.css.d.ts +18 -0
- package/dist/xyflow/nodes/element/element.css.js +31 -0
- package/dist/xyflow/nodes/element/index.d.ts +1 -0
- package/dist/xyflow/nodes/shared/ElementIcon.d.ts +8 -0
- package/dist/xyflow/nodes/shared/ElementIcon.js +38 -0
- package/dist/xyflow/nodes/shared/Toolbar.d.ts +9 -0
- package/dist/xyflow/nodes/shared/Toolbar.js +436 -0
- package/dist/xyflow/types.d.ts +36 -0
- package/dist/xyflow/useLayoutConstraints.d.ts +42 -0
- package/dist/xyflow/useLayoutConstraints.js +226 -0
- package/dist/xyflow/useXYFlowEvents.d.ts +160 -0
- package/dist/xyflow/useXYFlowEvents.js +275 -0
- package/dist/xyflow/utils.d.ts +22 -0
- package/dist/xyflow/utils.js +72 -0
- package/package.json +40 -31
- package/src/LikeC4Diagram.props.ts +21 -12
- package/src/LikeC4Diagram.tsx +8 -10
- package/src/LikeC4Search.css.ts +12 -0
- package/src/LikeC4Search.tsx +45 -93
- package/src/controls/Text.ts +5 -0
- package/src/controls/action-button-bar/ActionButtonBar.css.ts +13 -0
- package/src/controls/action-button-bar/ActionButtonBar.tsx +138 -0
- package/src/controls/action-button-bar/useActionButtonBarCtx.ts +13 -0
- package/src/controls/action-buttons/ActionButton.css.ts +29 -0
- package/src/controls/action-buttons/ActionButton.tsx +66 -0
- package/src/controls/action-buttons/ActionButtons.tsx +138 -0
- package/src/hooks/useDiagramState.ts +8 -3
- package/src/hooks/useXYFlow.ts +9 -8
- package/src/index.ts +12 -6
- package/src/likec4model/index.ts +12 -2
- package/src/likec4model/useLikeC4ElementsTree.ts +6 -13
- package/src/likec4model/useLikeC4Model.ts +21 -11
- package/src/overlays/Overlays.tsx +96 -63
- package/src/overlays/edge-details/EdgeDetailsXYFlow.tsx +18 -10
- package/src/overlays/edge-details/_types.ts +13 -33
- package/src/overlays/edge-details/use-layouted-edge-details.ts +35 -26
- package/src/overlays/edge-details/xyflow/CompoundNode.tsx +3 -11
- package/src/overlays/edge-details/xyflow/ElementNode.tsx +8 -13
- package/src/overlays/edge-details/xyflow/RelationshipEdge.tsx +7 -7
- package/src/overlays/edge-details/xyflow/styles.css.ts +1 -59
- package/src/overlays/element-details/ElementDetailsCard.tsx +91 -78
- package/src/overlays/element-details/TabPanelDeployments.css.ts +69 -0
- package/src/overlays/element-details/TabPanelDeployments.tsx +217 -0
- package/src/overlays/element-details/TabPanelRelationships.tsx +8 -9
- package/src/overlays/element-details/TabPanelStructure.tsx +10 -10
- package/src/overlays/relationships-of/RelationshipsOverlay.tsx +1 -1
- package/src/overlays/relationships-of/RelationshipsXYFlow.tsx +26 -34
- package/src/overlays/relationships-of/SelectElement.tsx +2 -2
- package/src/overlays/relationships-of/_types.ts +20 -58
- package/src/overlays/relationships-of/use-layouted-relationships.ts +54 -59
- package/src/overlays/relationships-of/xyflow/CompoundNode.tsx +10 -16
- package/src/overlays/relationships-of/xyflow/ElementNode.tsx +24 -21
- package/src/overlays/relationships-of/xyflow/EmptyNode.tsx +4 -7
- package/src/overlays/relationships-of/xyflow/RelationshipEdge.tsx +16 -15
- package/src/overlays/shared/xyflow/RelationshipEdge.css.ts +60 -0
- package/src/overlays/shared/xyflow/_types.ts +87 -0
- package/src/state/diagram-to-xyflow.ts +6 -7
- package/src/state/diagramStore.layout.ts +3 -4
- package/src/state/diagramStore.ts +63 -48
- package/src/theme-vars.css.ts +81 -0
- package/src/theme-vars.ts +8 -81
- package/src/ui/DiagramTitlePanel.tsx +7 -34
- package/src/ui/Link.tsx +40 -0
- package/src/ui/notation/NotationPanel.tsx +4 -2
- package/src/ui/top-left/ChangeAutoLayoutButton.tsx +2 -2
- package/src/ui/top-left/TopLeftPanel.tsx +5 -5
- package/src/utils/types.ts +6 -0
- package/src/xyflow/SelectEdgesOnNodeFocus.tsx +3 -3
- package/src/xyflow/XYFlow.tsx +2 -2
- package/src/xyflow/edges/EdgeLabel.tsx +26 -19
- package/src/xyflow/edges/RelationshipEdge.tsx +5 -3
- package/src/xyflow/edges/RelationshipsDropdownMenu.tsx +23 -10
- package/src/xyflow/edges/edges.css.ts +68 -74
- package/src/xyflow/edges/utils.ts +6 -6
- package/src/xyflow/nodes/AnimateVariants.ts +143 -0
- package/src/xyflow/nodes/Node.css.ts +44 -0
- package/src/xyflow/nodes/compound/CompoundNode.css.ts +27 -75
- package/src/xyflow/nodes/compound/CompoundNode.tsx +82 -163
- package/src/xyflow/nodes/element/ElementLink.tsx +2 -3
- package/src/xyflow/nodes/element/ElementNode.tsx +73 -252
- package/src/xyflow/nodes/element/element.css.ts +40 -64
- package/src/xyflow/nodes/shared/ElementIcon.tsx +1 -1
- package/src/xyflow/nodes/shared/Toolbar.tsx +51 -35
- package/src/xyflow/types.ts +48 -51
- package/src/xyflow/useLayoutConstraints.ts +10 -10
- package/src/xyflow/useXYFlowEvents.ts +31 -35
- package/src/xyflow/utils.ts +2 -2
- package/src/ui/OptionsPanel.css.ts +0 -9
- package/src/ui/OptionsPanel.tsx +0 -70
- package/src/ui/options/EdgeOptions.tsx +0 -142
- package/src/ui/options/NodeOptions.tsx +0 -362
- package/src/xyflow/nodes/element/ElementDetails.css.ts +0 -101
- package/src/xyflow/nodes/element/ElementDetails.tsx +0 -393
- package/src/xyflow/nodes/use-animate-variants.tsx +0 -64
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Variants } from 'framer-motion'
|
|
2
|
+
import { createContext, useContext } from 'react'
|
|
3
|
+
|
|
4
|
+
export const ActionButtonBarContext = createContext<
|
|
5
|
+
{
|
|
6
|
+
variants: Variants
|
|
7
|
+
['data-animate-target']?: string
|
|
8
|
+
} | null
|
|
9
|
+
>(null)
|
|
10
|
+
|
|
11
|
+
export function useActionButtonBarCtx() {
|
|
12
|
+
return useContext(ActionButtonBarContext)
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { style } from '@vanilla-extract/css'
|
|
2
|
+
import { mantine, vars, whereLight } from '../../theme-vars'
|
|
3
|
+
|
|
4
|
+
export const btn = style({
|
|
5
|
+
pointerEvents: 'all',
|
|
6
|
+
color: vars.element.loContrast,
|
|
7
|
+
cursor: 'pointer',
|
|
8
|
+
backgroundColor: 'var(--ai-bg)',
|
|
9
|
+
'vars': {
|
|
10
|
+
'--ai-bg-idle': `color-mix(in srgb , ${vars.element.fill}, transparent 99%)`,
|
|
11
|
+
'--ai-bg': `var(--ai-bg-idle)`,
|
|
12
|
+
'--ai-bg-hover': `color-mix(in srgb , ${vars.element.fill} 65%, ${vars.element.stroke})`,
|
|
13
|
+
'--ai-hover': `color-mix(in srgb , ${vars.element.fill} 50%, ${vars.element.stroke})`,
|
|
14
|
+
},
|
|
15
|
+
':hover': {
|
|
16
|
+
boxShadow: mantine.shadows.md,
|
|
17
|
+
},
|
|
18
|
+
selectors: {
|
|
19
|
+
[`${whereLight} .likec4-compound-transparent &`]: {
|
|
20
|
+
color: vars.element.stroke,
|
|
21
|
+
opacity: 0.85,
|
|
22
|
+
vars: {
|
|
23
|
+
'--ai-bg-hover': `color-mix(in srgb , ${vars.element.fill}, transparent 20%)`,
|
|
24
|
+
'--ai-hover': `color-mix(in srgb , ${vars.element.fill}, transparent 10%)`,
|
|
25
|
+
'--ai-bg': `color-mix(in srgb , ${vars.element.fill}, transparent 99%)`,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type ActionIconProps, ActionIcon, Tooltip } from '@mantine/core'
|
|
2
|
+
import clsx from 'clsx'
|
|
3
|
+
import { type HTMLMotionProps, type Variants, m } from 'framer-motion'
|
|
4
|
+
import type { PropsWithoutRef } from 'react'
|
|
5
|
+
import { stopPropagation } from '../../xyflow/utils'
|
|
6
|
+
import { useActionButtonBarCtx } from '../action-button-bar/useActionButtonBarCtx'
|
|
7
|
+
import * as css from './ActionButton.css'
|
|
8
|
+
|
|
9
|
+
export type ActionButtonProps = PropsWithoutRef<
|
|
10
|
+
Omit<ActionIconProps & HTMLMotionProps<'div'>, 'onClick' | 'children'> & {
|
|
11
|
+
onClick: (e: React.MouseEvent) => void
|
|
12
|
+
IconComponent: React.ComponentType<any>
|
|
13
|
+
tooltipLabel?: string
|
|
14
|
+
}
|
|
15
|
+
>
|
|
16
|
+
|
|
17
|
+
const variants = {
|
|
18
|
+
idle: {
|
|
19
|
+
'--icon-scale': 'scale(1)',
|
|
20
|
+
'--ai-bg': 'var(--ai-bg-idle)',
|
|
21
|
+
},
|
|
22
|
+
hovered: {
|
|
23
|
+
'--icon-scale': 'scale(1)',
|
|
24
|
+
'--ai-bg': 'var(--ai-bg-hover)',
|
|
25
|
+
},
|
|
26
|
+
selected: {},
|
|
27
|
+
} satisfies Variants
|
|
28
|
+
variants['selected'] = variants['hovered']
|
|
29
|
+
|
|
30
|
+
export const ActionButton = ({
|
|
31
|
+
onClick: action,
|
|
32
|
+
IconComponent,
|
|
33
|
+
tooltipLabel,
|
|
34
|
+
...props
|
|
35
|
+
}: ActionButtonProps) => {
|
|
36
|
+
const ctx = useActionButtonBarCtx() ?? {
|
|
37
|
+
variants: variants,
|
|
38
|
+
}
|
|
39
|
+
return (
|
|
40
|
+
<Tooltip
|
|
41
|
+
fz="xs"
|
|
42
|
+
color="dark"
|
|
43
|
+
label={tooltipLabel ?? ''}
|
|
44
|
+
disabled={!tooltipLabel}
|
|
45
|
+
withinPortal={false}
|
|
46
|
+
offset={2}
|
|
47
|
+
openDelay={600}>
|
|
48
|
+
<ActionIcon
|
|
49
|
+
component={m.div}
|
|
50
|
+
className={clsx('nodrag nopan', css.btn)}
|
|
51
|
+
radius="md"
|
|
52
|
+
role="button"
|
|
53
|
+
onClick={action}
|
|
54
|
+
onDoubleClick={stopPropagation}
|
|
55
|
+
{...ctx}
|
|
56
|
+
{...props}
|
|
57
|
+
>
|
|
58
|
+
<IconComponent
|
|
59
|
+
style={{
|
|
60
|
+
width: '70%',
|
|
61
|
+
transform: 'var(--icon-scale)',
|
|
62
|
+
}} />
|
|
63
|
+
</ActionIcon>
|
|
64
|
+
</Tooltip>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { Fqn } from '@likec4/core'
|
|
2
|
+
import { IconFileSymlink, IconId, IconTransform, IconZoomScan } from '@tabler/icons-react'
|
|
3
|
+
import { useCallback } from 'react'
|
|
4
|
+
import { useDiagramState, useDiagramStoreApi } from '../../hooks'
|
|
5
|
+
import { type ActionButtonProps, ActionButton } from './ActionButton'
|
|
6
|
+
|
|
7
|
+
export type NodeActionButtonProps = Omit<ActionButtonProps, 'onClick' | 'IconComponent' | 'tooltipLabel'> & {
|
|
8
|
+
fqn: Fqn
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Browse Relationships
|
|
12
|
+
|
|
13
|
+
export const BrowseRelationshipsButton = ({
|
|
14
|
+
fqn,
|
|
15
|
+
...props
|
|
16
|
+
}: NodeActionButtonProps) => {
|
|
17
|
+
const {
|
|
18
|
+
openOverlay,
|
|
19
|
+
} = useDiagramState(s => ({
|
|
20
|
+
openOverlay: s.openOverlay,
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
const onBrowseRelationships = useCallback((e: React.MouseEvent) => {
|
|
24
|
+
e.stopPropagation()
|
|
25
|
+
openOverlay({ relationshipsOf: fqn })
|
|
26
|
+
}, [openOverlay, fqn])
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<ActionButton
|
|
30
|
+
{...props}
|
|
31
|
+
onClick={onBrowseRelationships}
|
|
32
|
+
IconComponent={IconTransform}
|
|
33
|
+
tooltipLabel="Browse relationships"
|
|
34
|
+
/>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Navigate to
|
|
39
|
+
// It triggers the onNavigateTo event from the xynode (node should have a navigateTo property)
|
|
40
|
+
export type NavigateToButtonProps = Omit<ActionButtonProps, 'onClick' | 'IconComponent' | 'tooltipLabel'> & {
|
|
41
|
+
xynodeId: string
|
|
42
|
+
}
|
|
43
|
+
export const NavigateToButton = ({
|
|
44
|
+
xynodeId,
|
|
45
|
+
...props
|
|
46
|
+
}: NavigateToButtonProps) => {
|
|
47
|
+
const store = useDiagramStoreApi()
|
|
48
|
+
|
|
49
|
+
const onNavigateTo = useCallback((e: React.MouseEvent) => {
|
|
50
|
+
e.stopPropagation()
|
|
51
|
+
store.getState().triggerOnNavigateTo(xynodeId, e)
|
|
52
|
+
}, [store, xynodeId])
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<ActionButton
|
|
56
|
+
{...props}
|
|
57
|
+
onClick={onNavigateTo}
|
|
58
|
+
IconComponent={IconZoomScan}
|
|
59
|
+
tooltipLabel="Open scoped view"
|
|
60
|
+
/>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Open details
|
|
65
|
+
const VariantsDetailsBtn = {
|
|
66
|
+
idle: {
|
|
67
|
+
'--ai-bg': 'var(--ai-bg-idle)',
|
|
68
|
+
scale: 1,
|
|
69
|
+
opacity: 0.5,
|
|
70
|
+
originX: 0.45,
|
|
71
|
+
originY: 0.55,
|
|
72
|
+
},
|
|
73
|
+
selected: {},
|
|
74
|
+
hovered: {
|
|
75
|
+
scale: 1.2,
|
|
76
|
+
opacity: 0.7,
|
|
77
|
+
},
|
|
78
|
+
'hovered:details': {
|
|
79
|
+
scale: 1.44,
|
|
80
|
+
opacity: 1,
|
|
81
|
+
},
|
|
82
|
+
'tap:details': {
|
|
83
|
+
scale: 1.15,
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
VariantsDetailsBtn['selected'] = VariantsDetailsBtn['hovered']
|
|
87
|
+
|
|
88
|
+
export const OpenDetailsButton = ({
|
|
89
|
+
fqn,
|
|
90
|
+
...props
|
|
91
|
+
}: NodeActionButtonProps) => {
|
|
92
|
+
const {
|
|
93
|
+
openOverlay,
|
|
94
|
+
} = useDiagramState(s => ({
|
|
95
|
+
openOverlay: s.openOverlay,
|
|
96
|
+
}))
|
|
97
|
+
|
|
98
|
+
const onOpenDetails = useCallback((e: React.MouseEvent) => {
|
|
99
|
+
e.stopPropagation()
|
|
100
|
+
openOverlay({ elementDetails: fqn })
|
|
101
|
+
}, [openOverlay, fqn])
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<ActionButton
|
|
105
|
+
variants={VariantsDetailsBtn}
|
|
106
|
+
onClick={onOpenDetails}
|
|
107
|
+
IconComponent={IconId}
|
|
108
|
+
tooltipLabel="Open details"
|
|
109
|
+
data-animate-target="details"
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Open element source
|
|
116
|
+
|
|
117
|
+
export const OpenSourceButton = ({
|
|
118
|
+
fqn,
|
|
119
|
+
...props
|
|
120
|
+
}: NodeActionButtonProps) => {
|
|
121
|
+
const diagramApi = useDiagramStoreApi()
|
|
122
|
+
|
|
123
|
+
const onOpenSource = useCallback((e: React.MouseEvent) => {
|
|
124
|
+
e.stopPropagation()
|
|
125
|
+
diagramApi.getState().onOpenSource?.({
|
|
126
|
+
element: fqn,
|
|
127
|
+
})
|
|
128
|
+
}, [diagramApi, fqn])
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<ActionButton
|
|
132
|
+
{...props}
|
|
133
|
+
onClick={onOpenSource}
|
|
134
|
+
IconComponent={IconFileSymlink}
|
|
135
|
+
tooltipLabel="Open source"
|
|
136
|
+
/>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
@@ -2,10 +2,16 @@ import { shallowEqual } from 'fast-equals'
|
|
|
2
2
|
import { useContext } from 'react'
|
|
3
3
|
import { useStoreWithEqualityFn as useZustandStore } from 'zustand/traditional'
|
|
4
4
|
|
|
5
|
+
import type { ViewId } from '@likec4/core'
|
|
5
6
|
import { DiagramContext } from '../state/DiagramContext'
|
|
6
7
|
import type { DiagramState, DiagramStoreApi } from '../state/diagramStore'
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
const selectViewId = (state: DiagramState) => state.view.id
|
|
10
|
+
export function useCurrentViewId(): ViewId {
|
|
11
|
+
return useDiagramState(selectViewId)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function useDiagramState<StateSlice = unknown>(
|
|
9
15
|
selector: (state: DiagramState) => StateSlice,
|
|
10
16
|
equalityFn?: (a: StateSlice, b: StateSlice) => boolean
|
|
11
17
|
): StateSlice {
|
|
@@ -18,7 +24,7 @@ function useDiagramState<StateSlice = unknown>(
|
|
|
18
24
|
return useZustandStore(store, selector, equalityFn ?? shallowEqual)
|
|
19
25
|
}
|
|
20
26
|
|
|
21
|
-
function useDiagramStoreApi(): DiagramStoreApi {
|
|
27
|
+
export function useDiagramStoreApi(): DiagramStoreApi {
|
|
22
28
|
const store = useContext(DiagramContext)
|
|
23
29
|
|
|
24
30
|
if (store === null) {
|
|
@@ -28,4 +34,3 @@ function useDiagramStoreApi(): DiagramStoreApi {
|
|
|
28
34
|
return store
|
|
29
35
|
}
|
|
30
36
|
export type { DiagramState, DiagramStoreApi }
|
|
31
|
-
export { useDiagramState, useDiagramStoreApi }
|
package/src/hooks/useXYFlow.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { useNodesData, useReactFlow, useStore, useStoreApi } from '@xyflow/react'
|
|
1
|
+
import { useInternalNode, useNodesData, useReactFlow, useStore, useStoreApi } from '@xyflow/react'
|
|
2
2
|
import { deepEqual, shallowEqual } from 'fast-equals'
|
|
3
3
|
import { useCallback } from 'react'
|
|
4
|
-
import type {
|
|
4
|
+
import type { DiagramFlowTypes } from '../xyflow/types'
|
|
5
5
|
|
|
6
|
-
export const useXYFlow = useReactFlow<
|
|
6
|
+
export const useXYFlow = useReactFlow<DiagramFlowTypes.Node, DiagramFlowTypes.Edge>
|
|
7
7
|
|
|
8
|
-
export const useXYNodesData = useNodesData<
|
|
8
|
+
export const useXYNodesData = useNodesData<DiagramFlowTypes.Node>
|
|
9
|
+
export const useXYInternalNode = useInternalNode<DiagramFlowTypes.Node>
|
|
9
10
|
|
|
10
11
|
export function useXYStore<StateSlice = unknown>(
|
|
11
|
-
selector: (state: XYFlowState) => StateSlice,
|
|
12
|
+
selector: (state: DiagramFlowTypes.XYFlowState) => StateSlice,
|
|
12
13
|
equalityFn?: (a: StateSlice, b: StateSlice) => boolean
|
|
13
14
|
): StateSlice {
|
|
14
15
|
return useStore(
|
|
@@ -16,15 +17,15 @@ export function useXYStore<StateSlice = unknown>(
|
|
|
16
17
|
equalityFn ?? shallowEqual
|
|
17
18
|
)
|
|
18
19
|
}
|
|
19
|
-
export const useXYStoreApi = useStoreApi<
|
|
20
|
+
export const useXYStoreApi = useStoreApi<DiagramFlowTypes.Node, DiagramFlowTypes.Edge>
|
|
20
21
|
export type XYStoreApi = ReturnType<typeof useXYStoreApi>
|
|
21
22
|
|
|
22
|
-
export function useXYEdgesData(edgeIds: string[]): Pick<
|
|
23
|
+
export function useXYEdgesData(edgeIds: string[]): Pick<DiagramFlowTypes.Edge, 'id' | 'data'>[] {
|
|
23
24
|
const ids = edgeIds.join(',')
|
|
24
25
|
const edgesData = useXYStore(
|
|
25
26
|
useCallback(
|
|
26
27
|
(s) => {
|
|
27
|
-
const data = [] as Pick<
|
|
28
|
+
const data = [] as Pick<DiagramFlowTypes.Edge, 'id' | 'data'>[]
|
|
28
29
|
for (const id of edgeIds) {
|
|
29
30
|
const edge = s.edgeLookup.get(id)
|
|
30
31
|
if (edge) {
|
package/src/index.ts
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import '@xyflow/react/dist/style.css'
|
|
2
2
|
|
|
3
3
|
export { LikeC4Diagram } from './LikeC4Diagram'
|
|
4
|
+
export type { LikeC4DiagramProps } from './LikeC4Diagram'
|
|
5
|
+
|
|
4
6
|
export {
|
|
5
7
|
useLikeC4DiagramView,
|
|
8
|
+
useLikeC4ElementModel,
|
|
9
|
+
useLikeC4ElementsTree,
|
|
6
10
|
useLikeC4Model,
|
|
7
11
|
useLikeC4View,
|
|
8
12
|
useLikeC4ViewModel,
|
|
9
|
-
useLikeC4Views
|
|
10
|
-
} from './likec4model
|
|
13
|
+
useLikeC4Views,
|
|
14
|
+
} from './likec4model'
|
|
11
15
|
export { LikeC4ModelProvider } from './LikeC4ModelProvider'
|
|
12
|
-
export { StaticLikeC4Diagram } from './StaticLikeC4Diagram'
|
|
13
16
|
|
|
14
17
|
export { useSetState } from './hooks/useSetState'
|
|
15
18
|
export { useUpdateEffect } from './hooks/useUpdateEffect'
|
|
16
|
-
export
|
|
19
|
+
export { vars, xyvars } from './theme-vars'
|
|
20
|
+
|
|
17
21
|
export type * from './LikeC4Diagram.props'
|
|
18
|
-
|
|
19
|
-
export type * from './StaticLikeC4Diagram'
|
|
22
|
+
|
|
20
23
|
export type * from './xyflow/types'
|
|
24
|
+
|
|
25
|
+
export { StaticLikeC4Diagram } from './StaticLikeC4Diagram'
|
|
26
|
+
export type { StaticLikeC4DiagramProps } from './StaticLikeC4Diagram'
|
package/src/likec4model/index.ts
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export {
|
|
2
|
+
useLikeC4ElementsTree,
|
|
3
|
+
} from './useLikeC4ElementsTree'
|
|
4
|
+
export {
|
|
5
|
+
useLikeC4CurrentViewModel,
|
|
6
|
+
useLikeC4DiagramView,
|
|
7
|
+
useLikeC4ElementModel,
|
|
8
|
+
useLikeC4Model,
|
|
9
|
+
useLikeC4View,
|
|
10
|
+
useLikeC4ViewModel,
|
|
11
|
+
useLikeC4Views,
|
|
12
|
+
} from './useLikeC4Model'
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
compareNatural,
|
|
3
|
-
type Fqn,
|
|
4
|
-
type LikeC4DiagramModel,
|
|
5
|
-
type LikeC4Model,
|
|
6
|
-
type LikeC4ViewModel,
|
|
7
|
-
type ViewID
|
|
8
|
-
} from '@likec4/core'
|
|
1
|
+
import { compareNatural, type Fqn, type LikeC4Model, type ViewId } from '@likec4/core'
|
|
9
2
|
import { useMemo } from 'react'
|
|
10
3
|
import { useLikeC4Model } from './useLikeC4Model'
|
|
11
4
|
|
|
@@ -18,12 +11,12 @@ interface LikeC4ModelTreeNodeData {
|
|
|
18
11
|
const sortByLabel = (a: LikeC4ModelTreeNodeData, b: LikeC4ModelTreeNodeData) => compareNatural(a.label, b.label)
|
|
19
12
|
|
|
20
13
|
function buildNode(
|
|
21
|
-
element: LikeC4Model.
|
|
14
|
+
element: LikeC4Model.Node | LikeC4Model.Element
|
|
22
15
|
): LikeC4ModelTreeNodeData {
|
|
23
16
|
return {
|
|
24
17
|
label: element.title,
|
|
25
18
|
value: element.id,
|
|
26
|
-
children: element.children().map(buildNode).sort(sortByLabel)
|
|
19
|
+
children: [...element.children()].map(buildNode).sort(sortByLabel)
|
|
27
20
|
}
|
|
28
21
|
}
|
|
29
22
|
|
|
@@ -31,14 +24,14 @@ function buildNode(
|
|
|
31
24
|
* Returns a tree of elements in the model.
|
|
32
25
|
* If `viewId` is provided, returns the tree of elements in the view.
|
|
33
26
|
*/
|
|
34
|
-
export function useLikeC4ElementsTree(viewId?:
|
|
27
|
+
export function useLikeC4ElementsTree(viewId?: ViewId): LikeC4ModelTreeNodeData[] {
|
|
35
28
|
const model = useLikeC4Model(true)
|
|
36
29
|
return useMemo(() => {
|
|
37
30
|
if (viewId) {
|
|
38
31
|
const view = model.view(viewId)
|
|
39
|
-
return view.roots().map(buildNode).sort(sortByLabel)
|
|
32
|
+
return [...view.roots()].map(buildNode).sort(sortByLabel)
|
|
40
33
|
} else {
|
|
41
|
-
return model.roots().map(buildNode).sort(sortByLabel)
|
|
34
|
+
return [...model.roots()].map(buildNode).sort(sortByLabel)
|
|
42
35
|
}
|
|
43
36
|
}, [model, viewId ?? null])
|
|
44
37
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { type ComputedView, type DiagramView, type LikeC4Model, type
|
|
1
|
+
import { type ComputedView, type DiagramView, type Fqn, LikeC4Model, type ViewId } from '@likec4/core'
|
|
2
2
|
import { useContext } from 'react'
|
|
3
3
|
import { isDefined, isNonNullish, isString } from 'remeda'
|
|
4
4
|
import type { LiteralUnion } from 'type-fest'
|
|
5
|
+
import { useCurrentViewId } from '../hooks'
|
|
5
6
|
import { LikeC4ModelContext } from './LikeC4ModelContext'
|
|
6
7
|
|
|
7
8
|
export function useLikeC4Model(): LikeC4Model | null
|
|
@@ -9,11 +10,11 @@ export function useLikeC4Model(strict: true): LikeC4Model
|
|
|
9
10
|
export function useLikeC4Model(strict: boolean): LikeC4Model | null
|
|
10
11
|
export function useLikeC4Model(strict: true, type: 'layouted'): LikeC4Model.Layouted
|
|
11
12
|
export function useLikeC4Model(strict: true, type: 'computed'): LikeC4Model.Computed
|
|
12
|
-
export function useLikeC4Model(strict: true, type:
|
|
13
|
+
export function useLikeC4Model(strict: true, type: 'layouted' | 'computed' | undefined): LikeC4Model
|
|
13
14
|
export function useLikeC4Model(strict: boolean, type: 'layouted'): LikeC4Model.Layouted | null
|
|
14
15
|
export function useLikeC4Model(strict: boolean, type: 'computed'): LikeC4Model.Computed | null
|
|
15
|
-
export function useLikeC4Model(strict: boolean, type:
|
|
16
|
-
export function useLikeC4Model(strict?: boolean, type?:
|
|
16
|
+
export function useLikeC4Model(strict: boolean, type: 'layouted' | 'computed' | undefined): LikeC4Model | null
|
|
17
|
+
export function useLikeC4Model(strict?: boolean, type?: 'layouted' | 'computed') {
|
|
17
18
|
const model = useContext(LikeC4ModelContext)
|
|
18
19
|
|
|
19
20
|
if (isString(type) && isNonNullish(model) && model.type !== type) {
|
|
@@ -26,33 +27,42 @@ export function useLikeC4Model(strict?: boolean, type?: LikeC4Model['type']) {
|
|
|
26
27
|
return model
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
export function useLikeC4Views():
|
|
30
|
-
return useLikeC4Model(true).
|
|
30
|
+
export function useLikeC4Views(): Record<ViewId, ComputedView | DiagramView> {
|
|
31
|
+
return useLikeC4Model(true).$model.views
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
export function useLikeC4ViewModel(viewId: LiteralUnion<
|
|
34
|
+
export function useLikeC4ViewModel(viewId: LiteralUnion<ViewId, string>): LikeC4Model.View {
|
|
35
|
+
return useLikeC4Model(true).view(viewId)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function useLikeC4CurrentViewModel(): LikeC4Model.View {
|
|
39
|
+
const viewId = useCurrentViewId()
|
|
34
40
|
return useLikeC4Model(true).view(viewId)
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
/**
|
|
38
44
|
* Parsed view, computed or layouted
|
|
39
45
|
*/
|
|
40
|
-
export function useLikeC4View(viewId: LiteralUnion<
|
|
46
|
+
export function useLikeC4View(viewId: LiteralUnion<ViewId, string>): ComputedView | DiagramView | null {
|
|
41
47
|
const model = useLikeC4Model(true)
|
|
42
48
|
try {
|
|
43
|
-
return model.view(viewId)
|
|
49
|
+
return model.view(viewId).$view
|
|
44
50
|
} catch (error) {
|
|
45
51
|
console.warn(error)
|
|
46
52
|
return null
|
|
47
53
|
}
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
export function useLikeC4DiagramView(viewId: LiteralUnion<
|
|
56
|
+
export function useLikeC4DiagramView(viewId: LiteralUnion<ViewId, string>): DiagramView | null {
|
|
51
57
|
const model = useLikeC4Model(true, 'layouted')
|
|
52
58
|
try {
|
|
53
|
-
return model.view(viewId)
|
|
59
|
+
return model.view(viewId).$view
|
|
54
60
|
} catch (error) {
|
|
55
61
|
console.warn(error)
|
|
56
62
|
return null
|
|
57
63
|
}
|
|
58
64
|
}
|
|
65
|
+
|
|
66
|
+
export function useLikeC4ElementModel(fqn: LiteralUnion<Fqn, string>): LikeC4Model.Element {
|
|
67
|
+
return useLikeC4Model(true).element(fqn)
|
|
68
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ActionIcon, Box, FocusTrap, RemoveScroll } from '@mantine/core'
|
|
1
|
+
import { ActionIcon, Box, Button, FocusTrap, Group, Notification, RemoveScroll, Text } from '@mantine/core'
|
|
2
2
|
import { useHotkeys } from '@mantine/hooks'
|
|
3
3
|
import { IconX } from '@tabler/icons-react'
|
|
4
4
|
import { ReactFlowProvider as XYFlowProvider } from '@xyflow/react'
|
|
5
5
|
import { AnimatePresence, m } from 'framer-motion'
|
|
6
6
|
import { memo, type PropsWithChildren, useEffect, useMemo, useRef } from 'react'
|
|
7
|
+
import { ErrorBoundary, type FallbackProps } from 'react-error-boundary'
|
|
7
8
|
import { isNullish } from 'remeda'
|
|
8
9
|
import { type DiagramState, useDiagramState, useDiagramStoreApi } from '../hooks/useDiagramState'
|
|
9
10
|
import { EdgeDetailsXYFlow } from './edge-details/EdgeDetailsXYFlow'
|
|
@@ -12,6 +13,36 @@ import { OverlayContext, useOverlayDialog } from './OverlayContext'
|
|
|
12
13
|
import * as css from './Overlays.css'
|
|
13
14
|
import { RelationshipsOverlay } from './relationships-of/RelationshipsOverlay'
|
|
14
15
|
|
|
16
|
+
function Fallback({ error, resetErrorBoundary }: FallbackProps) {
|
|
17
|
+
// Call resetErrorBoundary() to reset the error boundary and retry the render.
|
|
18
|
+
const errorString = error instanceof Error ? error.message : 'Unknown error'
|
|
19
|
+
return (
|
|
20
|
+
<Box className={css.container} p={'lg'}>
|
|
21
|
+
<Notification
|
|
22
|
+
icon={<IconX style={{ width: 16, height: 16 }} />}
|
|
23
|
+
styles={{
|
|
24
|
+
icon: {
|
|
25
|
+
alignSelf: 'flex-start'
|
|
26
|
+
}
|
|
27
|
+
}}
|
|
28
|
+
color={'red'}
|
|
29
|
+
title={'Oops, something went wrong'}
|
|
30
|
+
py={'lg'}
|
|
31
|
+
withCloseButton={false}>
|
|
32
|
+
<Text
|
|
33
|
+
style={{
|
|
34
|
+
whiteSpace: 'preserve-breaks'
|
|
35
|
+
}}>
|
|
36
|
+
{errorString}
|
|
37
|
+
</Text>
|
|
38
|
+
<Group gap={'xs'} mt="sm">
|
|
39
|
+
<Button color="gray" size="xs" variant="light" onClick={() => resetErrorBoundary()}>Reset</Button>
|
|
40
|
+
</Group>
|
|
41
|
+
</Notification>
|
|
42
|
+
</Box>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
15
46
|
export const Overlays = memo(() => {
|
|
16
47
|
const diagramStore = useDiagramStoreApi()
|
|
17
48
|
const {
|
|
@@ -53,68 +84,70 @@ export const Overlays = memo(() => {
|
|
|
53
84
|
|
|
54
85
|
return (
|
|
55
86
|
<OverlayContext.Provider value={ctxValue}>
|
|
56
|
-
<
|
|
57
|
-
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
{
|
|
63
|
-
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
e
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
87
|
+
<ErrorBoundary FallbackComponent={Fallback} onReset={() => ctxValue.close()}>
|
|
88
|
+
<AnimatePresence initial={false} key={viewId} onExitComplete={onExitComplete}>
|
|
89
|
+
{activeOverlay?.elementDetails && (
|
|
90
|
+
<ElementDetailsCard key={'details card'} fqn={activeOverlay.elementDetails} />
|
|
91
|
+
)}
|
|
92
|
+
</AnimatePresence>
|
|
93
|
+
<AnimatePresence initial={false} onExitComplete={onExitComplete}>
|
|
94
|
+
{activeOverlay && isNullish(activeOverlay.elementDetails) && (
|
|
95
|
+
<RemoveScroll forwardProps>
|
|
96
|
+
<Box
|
|
97
|
+
component={m.div}
|
|
98
|
+
className={css.container}
|
|
99
|
+
data-likec4-color="gray"
|
|
100
|
+
initial={{
|
|
101
|
+
'--backdrop-blur': '0px',
|
|
102
|
+
'--backdrop-opacity': '0%',
|
|
103
|
+
opacity: 0,
|
|
104
|
+
translateY: -15
|
|
105
|
+
}}
|
|
106
|
+
animate={{
|
|
107
|
+
'--backdrop-blur': '10px',
|
|
108
|
+
'--backdrop-opacity': '70%',
|
|
109
|
+
opacity: 1,
|
|
110
|
+
translateY: 0
|
|
111
|
+
}}
|
|
112
|
+
exit={{
|
|
113
|
+
'--backdrop-blur': '1px',
|
|
114
|
+
'--backdrop-opacity': '0%',
|
|
115
|
+
translateY: -5,
|
|
116
|
+
opacity: 0,
|
|
117
|
+
transition: {
|
|
118
|
+
duration: .2
|
|
119
|
+
}
|
|
120
|
+
}}
|
|
121
|
+
>
|
|
122
|
+
<FocusTrap>
|
|
123
|
+
{activeOverlay.relationshipsOf && <RelationshipsOverlay subjectId={activeOverlay.relationshipsOf} />}
|
|
124
|
+
{activeOverlay.edgeDetails && (
|
|
125
|
+
<XYFlowProvider
|
|
126
|
+
defaultNodes={[]}
|
|
127
|
+
defaultEdges={[]}>
|
|
128
|
+
<EdgeDetailsXYFlow edgeId={activeOverlay.edgeDetails} />
|
|
129
|
+
</XYFlowProvider>
|
|
130
|
+
)}
|
|
131
|
+
<Box pos={'absolute'} top={'1rem'} right={'1rem'}>
|
|
132
|
+
<ActionIcon
|
|
133
|
+
variant="default"
|
|
134
|
+
// color="gray"
|
|
135
|
+
size={'lg'}
|
|
136
|
+
// data-autofocus
|
|
137
|
+
// autoFocus
|
|
138
|
+
onClick={(e) => {
|
|
139
|
+
e.stopPropagation()
|
|
140
|
+
ctxValue.close()
|
|
141
|
+
}}>
|
|
142
|
+
<IconX />
|
|
143
|
+
</ActionIcon>
|
|
144
|
+
</Box>
|
|
145
|
+
</FocusTrap>
|
|
146
|
+
</Box>
|
|
147
|
+
</RemoveScroll>
|
|
148
|
+
)}
|
|
149
|
+
</AnimatePresence>
|
|
150
|
+
</ErrorBoundary>
|
|
118
151
|
</OverlayContext.Provider>
|
|
119
152
|
)
|
|
120
153
|
})
|