@flanksource/clicky-ui 0.3.41 → 0.3.43
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/ai.cjs +4 -0
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +4 -0
- package/dist/ai.js.map +1 -1
- package/dist/comments/CommentCard.cjs +3 -1
- package/dist/comments/CommentCard.cjs.map +1 -1
- package/dist/comments/CommentCard.d.ts.map +1 -1
- package/dist/comments/CommentCard.js +4 -2
- package/dist/comments/CommentCard.js.map +1 -1
- package/dist/comments/CommentCardParts.cjs +16 -0
- package/dist/comments/CommentCardParts.cjs.map +1 -1
- package/dist/comments/CommentCardParts.d.ts +4 -1
- package/dist/comments/CommentCardParts.d.ts.map +1 -1
- package/dist/comments/CommentCardParts.js +16 -0
- package/dist/comments/CommentCardParts.js.map +1 -1
- package/dist/comments/comment-types.cjs.map +1 -1
- package/dist/comments/comment-types.d.ts +4 -0
- package/dist/comments/comment-types.d.ts.map +1 -1
- package/dist/comments/comment-types.js.map +1 -1
- package/dist/components/Combobox.cjs +54 -8
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +56 -10
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/ComboboxMenu.cjs +139 -113
- package/dist/components/ComboboxMenu.cjs.map +1 -1
- package/dist/components/ComboboxMenu.d.ts +3 -1
- package/dist/components/ComboboxMenu.d.ts.map +1 -1
- package/dist/components/ComboboxMenu.js +139 -113
- package/dist/components/ComboboxMenu.js.map +1 -1
- package/dist/components/ComboboxMenuTrigger.cjs +87 -0
- package/dist/components/ComboboxMenuTrigger.cjs.map +1 -0
- package/dist/components/ComboboxMenuTrigger.d.ts +23 -0
- package/dist/components/ComboboxMenuTrigger.d.ts.map +1 -0
- package/dist/components/ComboboxMenuTrigger.js +87 -0
- package/dist/components/ComboboxMenuTrigger.js.map +1 -0
- package/dist/components/JsonSchemaForm.cjs +30 -7
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +30 -7
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/SegmentedControl.cjs +20 -3
- package/dist/components/SegmentedControl.cjs.map +1 -1
- package/dist/components/SegmentedControl.d.ts +11 -0
- package/dist/components/SegmentedControl.d.ts.map +1 -1
- package/dist/components/SegmentedControl.js +21 -4
- package/dist/components/SegmentedControl.js.map +1 -1
- package/dist/components/combobox-types.d.ts +8 -0
- package/dist/components/combobox-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-debug-badge.cjs +108 -0
- package/dist/components/json-schema-form-debug-badge.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-badge.d.ts +10 -0
- package/dist/components/json-schema-form-debug-badge.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-badge.js +108 -0
- package/dist/components/json-schema-form-debug-badge.js.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs +129 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.d.ts +20 -0
- package/dist/components/json-schema-form-debug-glyph-map.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.js +129 -0
- package/dist/components/json-schema-form-debug-glyph-map.js.map +1 -0
- package/dist/components/json-schema-form-debug-glyph.cjs +13 -0
- package/dist/components/json-schema-form-debug-glyph.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-glyph.d.ts +6 -0
- package/dist/components/json-schema-form-debug-glyph.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-glyph.js +13 -0
- package/dist/components/json-schema-form-debug-glyph.js.map +1 -0
- package/dist/components/json-schema-form-debug-groups.cjs +56 -0
- package/dist/components/json-schema-form-debug-groups.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-groups.d.ts +8 -0
- package/dist/components/json-schema-form-debug-groups.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-groups.js +56 -0
- package/dist/components/json-schema-form-debug-groups.js.map +1 -0
- package/dist/components/json-schema-form-debug-keywords.cjs +159 -0
- package/dist/components/json-schema-form-debug-keywords.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-keywords.d.ts +6 -0
- package/dist/components/json-schema-form-debug-keywords.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-keywords.js +159 -0
- package/dist/components/json-schema-form-debug-keywords.js.map +1 -0
- package/dist/components/json-schema-form-debug-listeners.cjs +102 -0
- package/dist/components/json-schema-form-debug-listeners.cjs.map +1 -0
- package/dist/components/json-schema-form-debug-listeners.d.ts +6 -0
- package/dist/components/json-schema-form-debug-listeners.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug-listeners.js +102 -0
- package/dist/components/json-schema-form-debug-listeners.js.map +1 -0
- package/dist/components/json-schema-form-debug.cjs +31 -0
- package/dist/components/json-schema-form-debug.cjs.map +1 -0
- package/dist/components/json-schema-form-debug.d.ts +11 -0
- package/dist/components/json-schema-form-debug.d.ts.map +1 -0
- package/dist/components/json-schema-form-debug.js +31 -0
- package/dist/components/json-schema-form-debug.js.map +1 -0
- package/dist/components/json-schema-form-enum-choice.cjs +114 -0
- package/dist/components/json-schema-form-enum-choice.cjs.map +1 -0
- package/dist/components/json-schema-form-enum-choice.d.ts +14 -0
- package/dist/components/json-schema-form-enum-choice.d.ts.map +1 -0
- package/dist/components/json-schema-form-enum-choice.js +114 -0
- package/dist/components/json-schema-form-enum-choice.js.map +1 -0
- package/dist/components/json-schema-form-fields.cjs +3 -93
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +1 -91
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-listeners.cjs +7 -1
- package/dist/components/json-schema-form-listeners.cjs.map +1 -1
- package/dist/components/json-schema-form-listeners.d.ts.map +1 -1
- package/dist/components/json-schema-form-listeners.js +7 -1
- package/dist/components/json-schema-form-listeners.js.map +1 -1
- package/dist/components/json-schema-form-preferences.cjs +1 -0
- package/dist/components/json-schema-form-preferences.cjs.map +1 -1
- package/dist/components/json-schema-form-preferences.d.ts +1 -0
- package/dist/components/json-schema-form-preferences.d.ts.map +1 -1
- package/dist/components/json-schema-form-preferences.js +1 -0
- package/dist/components/json-schema-form-preferences.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +21 -5
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +21 -5
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-runtime-types.d.ts +1 -0
- package/dist/components/json-schema-form-runtime-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-tone.cjs +12 -0
- package/dist/components/json-schema-form-tone.cjs.map +1 -1
- package/dist/components/json-schema-form-tone.js +12 -0
- package/dist/components/json-schema-form-tone.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +1 -0
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/data/GraphDiagram.cjs +125 -138
- package/dist/data/GraphDiagram.cjs.map +1 -1
- package/dist/data/GraphDiagram.d.ts +30 -23
- package/dist/data/GraphDiagram.d.ts.map +1 -1
- package/dist/data/GraphDiagram.js +128 -141
- package/dist/data/GraphDiagram.js.map +1 -1
- package/dist/data/GraphDiagramEdges.cjs +208 -0
- package/dist/data/GraphDiagramEdges.cjs.map +1 -0
- package/dist/data/GraphDiagramEdges.d.ts +40 -0
- package/dist/data/GraphDiagramEdges.d.ts.map +1 -0
- package/dist/data/GraphDiagramEdges.js +208 -0
- package/dist/data/GraphDiagramEdges.js.map +1 -0
- package/dist/data/GraphDiagramNodes.cjs +142 -0
- package/dist/data/GraphDiagramNodes.cjs.map +1 -0
- package/dist/data/GraphDiagramNodes.d.ts +22 -0
- package/dist/data/GraphDiagramNodes.d.ts.map +1 -0
- package/dist/data/GraphDiagramNodes.js +142 -0
- package/dist/data/GraphDiagramNodes.js.map +1 -0
- package/dist/data/ai/PromptRunEditor/RuntimeRows.cjs +8 -3
- package/dist/data/ai/PromptRunEditor/RuntimeRows.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/RuntimeRows.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/RuntimeRows.js +8 -3
- package/dist/data/ai/PromptRunEditor/RuntimeRows.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.cjs +37 -43
- package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts +3 -1
- package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/index.js +38 -44
- package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs +16 -5
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.d.ts +4 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.js +17 -6
- package/dist/data/ai/PromptRunEditor/runtimeActions.js.map +1 -1
- package/dist/data/ai/SessionInspector.approvals-model.cjs +12 -0
- package/dist/data/ai/SessionInspector.approvals-model.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.approvals-model.d.ts +11 -2
- package/dist/data/ai/SessionInspector.approvals-model.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.approvals-model.js +12 -0
- package/dist/data/ai/SessionInspector.approvals-model.js.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.cjs +25 -1
- package/dist/data/ai/SessionInspector.approvals.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.js +26 -2
- package/dist/data/ai/SessionInspector.approvals.js.map +1 -1
- package/dist/data/ai/SessionInspector.summary.cjs +9 -3
- package/dist/data/ai/SessionInspector.summary.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.summary.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.summary.js +9 -3
- package/dist/data/ai/SessionInspector.summary.js.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.cjs +4 -0
- package/dist/data/ai/SessionInspector.transcript.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.js +4 -0
- package/dist/data/ai/SessionInspector.transcript.js.map +1 -1
- package/dist/data/ai/SessionViewer.approval-body.cjs +146 -0
- package/dist/data/ai/SessionViewer.approval-body.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.approval-body.d.ts +11 -0
- package/dist/data/ai/SessionViewer.approval-body.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.approval-body.js +146 -0
- package/dist/data/ai/SessionViewer.approval-body.js.map +1 -0
- package/dist/data/ai/SessionViewer.approval-forms.cjs +150 -0
- package/dist/data/ai/SessionViewer.approval-forms.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.approval-forms.d.ts +23 -0
- package/dist/data/ai/SessionViewer.approval-forms.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.approval-forms.js +150 -0
- package/dist/data/ai/SessionViewer.approval-forms.js.map +1 -0
- package/dist/data/ai/SessionViewer.cjs +57 -20
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +13 -3
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.decision-controls.cjs +313 -0
- package/dist/data/ai/SessionViewer.decision-controls.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.decision-controls.d.ts +43 -0
- package/dist/data/ai/SessionViewer.decision-controls.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.decision-controls.js +313 -0
- package/dist/data/ai/SessionViewer.decision-controls.js.map +1 -0
- package/dist/data/ai/SessionViewer.decision.cjs +21 -0
- package/dist/data/ai/SessionViewer.decision.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.decision.d.ts +12 -0
- package/dist/data/ai/SessionViewer.decision.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.decision.js +21 -0
- package/dist/data/ai/SessionViewer.decision.js.map +1 -0
- package/dist/data/ai/SessionViewer.input.cjs +14 -0
- package/dist/data/ai/SessionViewer.input.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.input.d.ts +5 -0
- package/dist/data/ai/SessionViewer.input.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.input.js +14 -0
- package/dist/data/ai/SessionViewer.input.js.map +1 -1
- package/dist/data/ai/SessionViewer.js +58 -21
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.model.d.ts +4 -0
- package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.model.js.map +1 -1
- package/dist/data/ai/SessionViewer.rows.cjs +6 -3
- package/dist/data/ai/SessionViewer.rows.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.rows.d.ts +2 -1
- package/dist/data/ai/SessionViewer.rows.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.rows.js +6 -3
- package/dist/data/ai/SessionViewer.rows.js.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.cjs +29 -237
- package/dist/data/ai/SessionViewer.tool-row.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.js +27 -235
- package/dist/data/ai/SessionViewer.tool-row.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +4 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.cjs +8 -2
- package/dist/data/ai/SessionViewerMenu.cjs.map +1 -1
- package/dist/data/ai/SessionViewerMenu.d.ts +4 -1
- package/dist/data/ai/SessionViewerMenu.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.js +8 -2
- package/dist/data/ai/SessionViewerMenu.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs +28 -17
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts +10 -2
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js +29 -18
- package/dist/data/ai/SpecRuntimeEditor/CommitSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.cjs +9 -1
- package/dist/data/ai/SpecRuntimeEditor/index.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts +9 -2
- package/dist/data/ai/SpecRuntimeEditor/index.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/index.js +9 -1
- package/dist/data/ai/SpecRuntimeEditor/index.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.cjs +1 -1
- package/dist/data/ai/SpecRuntimeEditor/permission-mode-visuals.js +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts +8 -2
- package/dist/data/ai/SpecRuntimeEditor/summaries.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/summaries.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.cjs +14 -6
- package/dist/data/ai/SpecRuntimeEditor/update.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts +1 -0
- package/dist/data/ai/SpecRuntimeEditor/update.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/update.js +14 -6
- package/dist/data/ai/SpecRuntimeEditor/update.js.map +1 -1
- package/dist/data/ai/approval-request.cjs +75 -0
- package/dist/data/ai/approval-request.cjs.map +1 -0
- package/dist/data/ai/approval-request.d.ts +155 -0
- package/dist/data/ai/approval-request.d.ts.map +1 -0
- package/dist/data/ai/approval-request.js +75 -0
- package/dist/data/ai/approval-request.js.map +1 -0
- package/dist/data/ai/index.d.ts +3 -0
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.cjs +125 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.cjs.map +1 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.d.ts +11 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.js +125 -0
- package/dist/data/ai/runtime-preset-menu/SavePresetDialog.js.map +1 -0
- package/dist/data/ai/runtime-preset-menu/index.d.ts +3 -0
- package/dist/data/ai/runtime-preset-menu/index.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/model.cjs +73 -0
- package/dist/data/ai/runtime-preset-menu/model.cjs.map +1 -0
- package/dist/data/ai/runtime-preset-menu/model.d.ts +13 -0
- package/dist/data/ai/runtime-preset-menu/model.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/model.js +73 -0
- package/dist/data/ai/runtime-preset-menu/model.js.map +1 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.cjs +149 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.cjs.map +1 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.d.ts +15 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.d.ts.map +1 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.js +149 -0
- package/dist/data/ai/runtime-preset-menu/use-runtime-preset-menu.js.map +1 -0
- package/dist/data/ai/runtime-spec-fields.cjs +166 -0
- package/dist/data/ai/runtime-spec-fields.cjs.map +1 -0
- package/dist/data/ai/runtime-spec-fields.d.ts +13 -0
- package/dist/data/ai/runtime-spec-fields.d.ts.map +1 -0
- package/dist/data/ai/runtime-spec-fields.js +166 -0
- package/dist/data/ai/runtime-spec-fields.js.map +1 -0
- package/dist/data/ai/session-categories.cjs +4 -0
- package/dist/data/ai/session-categories.cjs.map +1 -1
- package/dist/data/ai/session-categories.d.ts +1 -0
- package/dist/data/ai/session-categories.d.ts.map +1 -1
- package/dist/data/ai/session-categories.js +4 -0
- package/dist/data/ai/session-categories.js.map +1 -1
- package/dist/data/ai/use-session-scroll.cjs +49 -21
- package/dist/data/ai/use-session-scroll.cjs.map +1 -1
- package/dist/data/ai/use-session-scroll.d.ts +2 -0
- package/dist/data/ai/use-session-scroll.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.js +49 -21
- package/dist/data/ai/use-session-scroll.js.map +1 -1
- package/dist/data/chat/Chat.runtime.cjs +1 -1
- package/dist/data/chat/Chat.runtime.cjs.map +1 -1
- package/dist/data/chat/Chat.runtime.d.ts.map +1 -1
- package/dist/data/chat/Chat.runtime.js +1 -1
- package/dist/data/chat/Chat.runtime.js.map +1 -1
- package/dist/data/graph-columns-layout.cjs +216 -0
- package/dist/data/graph-columns-layout.cjs.map +1 -0
- package/dist/data/graph-columns-layout.d.ts +56 -0
- package/dist/data/graph-columns-layout.d.ts.map +1 -0
- package/dist/data/graph-columns-layout.js +216 -0
- package/dist/data/graph-columns-layout.js.map +1 -0
- package/dist/data/graph-diagram-model.cjs +73 -0
- package/dist/data/graph-diagram-model.cjs.map +1 -0
- package/dist/data/graph-diagram-model.d.ts +90 -0
- package/dist/data/graph-diagram-model.d.ts.map +1 -0
- package/dist/data/graph-diagram-model.js +73 -0
- package/dist/data/graph-diagram-model.js.map +1 -0
- package/dist/data/graph-edge-routing.cjs +235 -0
- package/dist/data/graph-edge-routing.cjs.map +1 -0
- package/dist/data/graph-edge-routing.d.ts +73 -0
- package/dist/data/graph-edge-routing.d.ts.map +1 -0
- package/dist/data/graph-edge-routing.js +235 -0
- package/dist/data/graph-edge-routing.js.map +1 -0
- package/dist/data/graph-layout.cjs +0 -82
- package/dist/data/graph-layout.cjs.map +1 -1
- package/dist/data/graph-layout.d.ts +1 -28
- package/dist/data/graph-layout.d.ts.map +1 -1
- package/dist/data/graph-layout.js +1 -83
- package/dist/data/graph-layout.js.map +1 -1
- package/dist/data/har/HarPanel.cjs +129 -33
- package/dist/data/har/HarPanel.cjs.map +1 -1
- package/dist/data/har/HarPanel.d.ts +13 -1
- package/dist/data/har/HarPanel.d.ts.map +1 -1
- package/dist/data/har/HarPanel.js +130 -34
- package/dist/data/har/HarPanel.js.map +1 -1
- package/dist/data/har/fixtures.d.ts +12 -0
- package/dist/data/har/fixtures.d.ts.map +1 -1
- package/dist/data/har/types.d.ts +12 -0
- package/dist/data/har/types.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.cjs +67 -84
- package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.d.ts +4 -5
- package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.fields.cjs +170 -0
- package/dist/data/runtime/RuntimeBar.fields.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBar.fields.d.ts +16 -0
- package/dist/data/runtime/RuntimeBar.fields.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.fields.js +170 -0
- package/dist/data/runtime/RuntimeBar.fields.js.map +1 -0
- package/dist/data/runtime/RuntimeBar.js +70 -87
- package/dist/data/runtime/RuntimeBar.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.cjs +56 -0
- package/dist/data/runtime/RuntimeBar.selection.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBar.selection.d.ts +20 -0
- package/dist/data/runtime/RuntimeBar.selection.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.selection.js +56 -0
- package/dist/data/runtime/RuntimeBar.selection.js.map +1 -0
- package/dist/data/runtime/RuntimeBarActions.cjs +10 -6
- package/dist/data/runtime/RuntimeBarActions.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts +8 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.js +10 -6
- package/dist/data/runtime/RuntimeBarActions.js.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.cjs +166 -0
- package/dist/data/runtime/RuntimeBarIdentity.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBarIdentity.d.ts +25 -0
- package/dist/data/runtime/RuntimeBarIdentity.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBarIdentity.js +166 -0
- package/dist/data/runtime/RuntimeBarIdentity.js.map +1 -0
- package/dist/data/runtime/RuntimeBarLayout.cjs +95 -0
- package/dist/data/runtime/RuntimeBarLayout.cjs.map +1 -0
- package/dist/data/runtime/RuntimeBarLayout.d.ts +9 -0
- package/dist/data/runtime/RuntimeBarLayout.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBarLayout.js +95 -0
- package/dist/data/runtime/RuntimeBarLayout.js.map +1 -0
- package/dist/data/runtime/RuntimeBarSegment.cjs +25 -14
- package/dist/data/runtime/RuntimeBarSegment.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.d.ts +4 -0
- package/dist/data/runtime/RuntimeBarSegment.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.js +25 -14
- package/dist/data/runtime/RuntimeBarSegment.js.map +1 -1
- package/dist/data/runtime/RuntimeLimitInput.cjs +41 -0
- package/dist/data/runtime/RuntimeLimitInput.cjs.map +1 -0
- package/dist/data/runtime/RuntimeLimitInput.d.ts +9 -0
- package/dist/data/runtime/RuntimeLimitInput.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeLimitInput.js +41 -0
- package/dist/data/runtime/RuntimeLimitInput.js.map +1 -0
- package/dist/data/runtime/use-runtime-bar-overflow.cjs +70 -0
- package/dist/data/runtime/use-runtime-bar-overflow.cjs.map +1 -0
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts +13 -0
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts.map +1 -0
- package/dist/data/runtime/use-runtime-bar-overflow.js +70 -0
- package/dist/data/runtime/use-runtime-bar-overflow.js.map +1 -0
- package/dist/data/use-edge-focus.cjs +20 -0
- package/dist/data/use-edge-focus.cjs.map +1 -0
- package/dist/data/use-edge-focus.d.ts +23 -0
- package/dist/data/use-edge-focus.d.ts.map +1 -0
- package/dist/data/use-edge-focus.js +20 -0
- package/dist/data/use-edge-focus.js.map +1 -0
- package/dist/data/use-pan-zoom.cjs +159 -0
- package/dist/data/use-pan-zoom.cjs.map +1 -0
- package/dist/data/use-pan-zoom.d.ts +79 -0
- package/dist/data/use-pan-zoom.d.ts.map +1 -0
- package/dist/data/use-pan-zoom.js +159 -0
- package/dist/data/use-pan-zoom.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +5 -1
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +4 -3
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +6 -2
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/overlay/DropdownMenu.cjs +1 -0
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts +4 -0
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js +1 -0
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.cjs +31 -15
- package/dist/overlay/DropdownMenuSubmenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.js +31 -15
- package/dist/overlay/DropdownMenuSubmenu.js.map +1 -1
- package/dist/profiles/fields/profileFieldFilterEditor.cjs +5 -2
- package/dist/profiles/fields/profileFieldFilterEditor.cjs.map +1 -1
- package/dist/profiles/fields/profileFieldFilterEditor.js +5 -2
- package/dist/profiles/fields/profileFieldFilterEditor.js.map +1 -1
- package/dist/profiles/fields/profileFieldIcons.cjs +2 -0
- package/dist/profiles/fields/profileFieldIcons.cjs.map +1 -1
- package/dist/profiles/fields/profileFieldIcons.d.ts.map +1 -1
- package/dist/profiles/fields/profileFieldIcons.js +2 -0
- package/dist/profiles/fields/profileFieldIcons.js.map +1 -1
- package/dist/profiles/wizard/profileWizardModel.cjs +1 -0
- package/dist/profiles/wizard/profileWizardModel.cjs.map +1 -1
- package/dist/profiles/wizard/profileWizardModel.d.ts +3 -0
- package/dist/profiles/wizard/profileWizardModel.d.ts.map +1 -1
- package/dist/profiles/wizard/profileWizardModel.js +1 -0
- package/dist/profiles/wizard/profileWizardModel.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +3 -1
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +3 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +3 -1
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/useOperationPages.cjs +6 -1
- package/dist/rpc/useOperationPages.cjs.map +1 -1
- package/dist/rpc/useOperationPages.d.ts +3 -1
- package/dist/rpc/useOperationPages.d.ts.map +1 -1
- package/dist/rpc/useOperationPages.js +6 -1
- package/dist/rpc/useOperationPages.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/schemas/json-schema-form.schema.json +5 -0
- package/dist/data/runtime/RuntimeBarCombo.cjs +0 -423
- package/dist/data/runtime/RuntimeBarCombo.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBarCombo.d.ts +0 -33
- package/dist/data/runtime/RuntimeBarCombo.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBarCombo.js +0 -423
- package/dist/data/runtime/RuntimeBarCombo.js.map +0 -1
- package/dist/data/runtime/RuntimeBarLimits.cjs +0 -262
- package/dist/data/runtime/RuntimeBarLimits.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBarLimits.d.ts +0 -17
- package/dist/data/runtime/RuntimeBarLimits.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBarLimits.js +0 -262
- package/dist/data/runtime/RuntimeBarLimits.js.map +0 -1
- package/dist/data/runtime/RuntimeBarSegments.cjs +0 -346
- package/dist/data/runtime/RuntimeBarSegments.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBarSegments.d.ts +0 -37
- package/dist/data/runtime/RuntimeBarSegments.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBarSegments.js +0 -346
- package/dist/data/runtime/RuntimeBarSegments.js.map +0 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { EdgeRoute } from './graph-edge-routing.js';
|
|
2
|
+
import { EdgeFocusState } from './use-edge-focus.js';
|
|
3
|
+
import { GraphDiagramEdge, GraphDiagramNode, GraphPlacer } from './graph-diagram-model.js';
|
|
4
|
+
interface EdgeSelection {
|
|
5
|
+
selectedEdgeId: string | undefined;
|
|
6
|
+
onEdgeSelect: ((id: string) => void) | undefined;
|
|
7
|
+
/** Set when the diagram is focused: see `GraphDiagramEdgeFocus`. */
|
|
8
|
+
focus: EdgeFocusState | undefined;
|
|
9
|
+
}
|
|
10
|
+
export interface GraphDiagramEdgePathsProps extends EdgeSelection {
|
|
11
|
+
edges: GraphDiagramEdge[];
|
|
12
|
+
nodes: GraphDiagramNode[];
|
|
13
|
+
routes: Record<string, EdgeRoute>;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
ariaLabel: string;
|
|
17
|
+
/** Unique per diagram instance, so two diagrams on a page never share marker ids. */
|
|
18
|
+
markerPrefix: string;
|
|
19
|
+
onEdgeHover: ((id: string | undefined) => void) | undefined;
|
|
20
|
+
}
|
|
21
|
+
export declare function GraphDiagramEdgePaths({ edges, nodes, routes, width, height, ariaLabel, markerPrefix, selectedEdgeId, onEdgeSelect, focus, onEdgeHover, }: GraphDiagramEdgePathsProps): import("react").JSX.Element;
|
|
22
|
+
export interface GraphDiagramEdgeLabelsProps extends EdgeSelection {
|
|
23
|
+
edges: GraphDiagramEdge[];
|
|
24
|
+
routes: Record<string, EdgeRoute>;
|
|
25
|
+
place: GraphPlacer;
|
|
26
|
+
/**
|
|
27
|
+
* Move pills that would cover one another apart. Only meaningful when the
|
|
28
|
+
* stage is drawn at its natural size, where a pill's px size and the layout
|
|
29
|
+
* share one coordinate system.
|
|
30
|
+
*/
|
|
31
|
+
spread: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The label pills, drawn as HTML over the edges. With `onEdgeSelect` a pill is
|
|
35
|
+
* a pointer shortcut for its edge; the edge's own path stays the one
|
|
36
|
+
* keyboard and screen-reader target, so the pill is hidden from both.
|
|
37
|
+
*/
|
|
38
|
+
export declare function GraphDiagramEdgeLabels({ edges, routes, place, spread, selectedEdgeId, onEdgeSelect, focus, }: GraphDiagramEdgeLabelsProps): import("react").JSX.Element;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=GraphDiagramEdges.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphDiagramEdges.d.ts","sourceRoot":"","sources":["../../src/data/GraphDiagramEdges.tsx"],"names":[],"mappings":"AACA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAElF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAQL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAS/B,UAAU,aAAa;IACrB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACjD,oEAAoE;IACpE,KAAK,EAAE,cAAc,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,0BAA2B,SAAQ,aAAa;IAC/D,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7D;AAgED,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,KAAK,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,SAAS,EACT,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,KAAK,EACL,WAAW,GACZ,EAAE,0BAA0B,+BA8C5B;AAED,MAAM,WAAW,2BAA4B,SAAQ,aAAa;IAChE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AA0DD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,KAAK,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,cAAc,EACd,YAAY,EACZ,KAAK,GACN,EAAE,2BAA2B,+BAsC7B"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { pointOnCurve, spreadLabels } from "./graph-edge-routing.js";
|
|
4
|
+
import { nodeName, TONE_TEXT_CLASS, edgeName, requireEntry, activateOnKey, hoverHandlers, edgeLabelWidth } from "./graph-diagram-model.js";
|
|
5
|
+
const ARROW_SIZE = 10.5;
|
|
6
|
+
const EDGE_STROKE = 1.5;
|
|
7
|
+
const SELECTED_EDGE_STROKE = 2.75;
|
|
8
|
+
const HIT_STROKE = 14;
|
|
9
|
+
function EdgePath({
|
|
10
|
+
edge,
|
|
11
|
+
d,
|
|
12
|
+
markerId,
|
|
13
|
+
name,
|
|
14
|
+
selected,
|
|
15
|
+
dimmed,
|
|
16
|
+
onSelect,
|
|
17
|
+
onHover
|
|
18
|
+
}) {
|
|
19
|
+
return /* @__PURE__ */ jsxs(
|
|
20
|
+
"g",
|
|
21
|
+
{
|
|
22
|
+
"data-graph-edge": edge.id,
|
|
23
|
+
className: cn("transition-opacity", dimmed && "opacity-20"),
|
|
24
|
+
...dimmed ? { "data-graph-edge-dimmed": "" } : {},
|
|
25
|
+
...onHover ? hoverHandlers(edge.id, onHover) : {},
|
|
26
|
+
children: [
|
|
27
|
+
edge.title !== void 0 && /* @__PURE__ */ jsx("title", { children: edge.title }),
|
|
28
|
+
/* @__PURE__ */ jsx(
|
|
29
|
+
"path",
|
|
30
|
+
{
|
|
31
|
+
d,
|
|
32
|
+
fill: "none",
|
|
33
|
+
stroke: "currentColor",
|
|
34
|
+
strokeWidth: selected ? SELECTED_EDGE_STROKE : EDGE_STROKE,
|
|
35
|
+
strokeDasharray: edge.dashed ? "5 4" : void 0,
|
|
36
|
+
pointerEvents: "visibleStroke",
|
|
37
|
+
markerEnd: `url(#${markerId})`,
|
|
38
|
+
className: TONE_TEXT_CLASS[edge.tone ?? "neutral"]
|
|
39
|
+
}
|
|
40
|
+
),
|
|
41
|
+
onSelect && /* @__PURE__ */ jsx(
|
|
42
|
+
"path",
|
|
43
|
+
{
|
|
44
|
+
d,
|
|
45
|
+
fill: "none",
|
|
46
|
+
stroke: "transparent",
|
|
47
|
+
strokeWidth: HIT_STROKE,
|
|
48
|
+
strokeLinecap: "round",
|
|
49
|
+
pointerEvents: "stroke",
|
|
50
|
+
role: "button",
|
|
51
|
+
tabIndex: 0,
|
|
52
|
+
"aria-label": name,
|
|
53
|
+
"aria-pressed": selected,
|
|
54
|
+
className: cn(
|
|
55
|
+
"cursor-pointer outline-none hover:stroke-primary/15 focus-visible:stroke-primary/30",
|
|
56
|
+
selected && "stroke-primary/15"
|
|
57
|
+
),
|
|
58
|
+
onClick: onSelect,
|
|
59
|
+
onKeyDown: (event) => activateOnKey(event, onSelect)
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function GraphDiagramEdgePaths({
|
|
67
|
+
edges,
|
|
68
|
+
nodes,
|
|
69
|
+
routes,
|
|
70
|
+
width,
|
|
71
|
+
height,
|
|
72
|
+
ariaLabel,
|
|
73
|
+
markerPrefix,
|
|
74
|
+
selectedEdgeId,
|
|
75
|
+
onEdgeSelect,
|
|
76
|
+
focus,
|
|
77
|
+
onEdgeHover
|
|
78
|
+
}) {
|
|
79
|
+
const tones = Array.from(new Set(edges.map((edge) => edge.tone ?? "neutral")));
|
|
80
|
+
const names = Object.fromEntries(nodes.map((node) => [node.id, nodeName(node)]));
|
|
81
|
+
return /* @__PURE__ */ jsxs(
|
|
82
|
+
"svg",
|
|
83
|
+
{
|
|
84
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
85
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
86
|
+
role: onEdgeSelect ? "group" : "img",
|
|
87
|
+
"aria-label": ariaLabel,
|
|
88
|
+
className: "pointer-events-none absolute inset-0 h-full w-full",
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ jsx("defs", { children: tones.map((tone) => /* @__PURE__ */ jsx(
|
|
91
|
+
"marker",
|
|
92
|
+
{
|
|
93
|
+
id: `${markerPrefix}-arrow-${tone}`,
|
|
94
|
+
viewBox: "0 0 10 10",
|
|
95
|
+
refX: 8,
|
|
96
|
+
refY: 5,
|
|
97
|
+
markerUnits: "userSpaceOnUse",
|
|
98
|
+
markerWidth: ARROW_SIZE,
|
|
99
|
+
markerHeight: ARROW_SIZE,
|
|
100
|
+
orient: "auto-start-reverse",
|
|
101
|
+
children: /* @__PURE__ */ jsx("path", { d: "M0,0 L10,5 L0,10 z", className: cn(TONE_TEXT_CLASS[tone], "fill-current") })
|
|
102
|
+
},
|
|
103
|
+
tone
|
|
104
|
+
)) }),
|
|
105
|
+
edges.map((edge) => /* @__PURE__ */ jsx(
|
|
106
|
+
EdgePath,
|
|
107
|
+
{
|
|
108
|
+
edge,
|
|
109
|
+
d: requireEntry(routes, edge.id, "route").path,
|
|
110
|
+
markerId: `${markerPrefix}-arrow-${edge.tone ?? "neutral"}`,
|
|
111
|
+
name: edgeName(edge, names),
|
|
112
|
+
selected: edge.id === selectedEdgeId,
|
|
113
|
+
dimmed: focus !== void 0 && focus.focused.size > 0 && !focus.focused.has(edge.id),
|
|
114
|
+
onSelect: onEdgeSelect ? () => onEdgeSelect(edge.id) : void 0,
|
|
115
|
+
onHover: onEdgeHover
|
|
116
|
+
},
|
|
117
|
+
edge.id
|
|
118
|
+
))
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
const LABEL_HEIGHT = 19;
|
|
124
|
+
const LABEL_LOOP_GAP = 6;
|
|
125
|
+
const FOCUS_LABEL_T = 0.65;
|
|
126
|
+
const LABEL_NODE_GAP = 4;
|
|
127
|
+
const ANCHOR_CLASS = {
|
|
128
|
+
start: "translate-x-1.5",
|
|
129
|
+
end: "-translate-x-[calc(100%+0.375rem)]",
|
|
130
|
+
center: "-translate-x-1/2"
|
|
131
|
+
};
|
|
132
|
+
function hasPill(edge) {
|
|
133
|
+
return Boolean(edge.label) || edge.icon != null;
|
|
134
|
+
}
|
|
135
|
+
function labelPoint(edge, route, focus) {
|
|
136
|
+
const middle = { x: route.labelX, y: route.labelY };
|
|
137
|
+
if (!route.curve || !focus || focus.nodes.has(edge.from) === focus.nodes.has(edge.to)) return middle;
|
|
138
|
+
const point = pointOnCurve(route.curve, focus.nodes.has(edge.from) ? FOCUS_LABEL_T : 1 - FOCUS_LABEL_T);
|
|
139
|
+
const reserved = edgeLabelWidth(edge) / 2 + LABEL_NODE_GAP;
|
|
140
|
+
const left = Math.min(route.curve[0].x, route.curve[3].x) + reserved;
|
|
141
|
+
const right = Math.max(route.curve[0].x, route.curve[3].x) - reserved;
|
|
142
|
+
return left > right ? { x: middle.x, y: point.y } : { x: Math.min(right, Math.max(left, point.x)), y: point.y };
|
|
143
|
+
}
|
|
144
|
+
function labelYs(edges, routes, points) {
|
|
145
|
+
return spreadLabels(
|
|
146
|
+
edges.map((edge) => {
|
|
147
|
+
const { labelAnchor } = requireEntry(routes, edge.id, "route");
|
|
148
|
+
const point = requireEntry(points, edge.id, "label point");
|
|
149
|
+
const outside = labelAnchor === void 0 ? 0 : labelAnchor === "start" ? LABEL_LOOP_GAP : -LABEL_LOOP_GAP;
|
|
150
|
+
return {
|
|
151
|
+
id: edge.id,
|
|
152
|
+
x: point.x + outside,
|
|
153
|
+
y: point.y,
|
|
154
|
+
width: edgeLabelWidth(edge),
|
|
155
|
+
height: LABEL_HEIGHT,
|
|
156
|
+
...labelAnchor ? { anchor: labelAnchor } : {}
|
|
157
|
+
};
|
|
158
|
+
})
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
function GraphDiagramEdgeLabels({
|
|
162
|
+
edges,
|
|
163
|
+
routes,
|
|
164
|
+
place,
|
|
165
|
+
spread,
|
|
166
|
+
selectedEdgeId,
|
|
167
|
+
onEdgeSelect,
|
|
168
|
+
focus
|
|
169
|
+
}) {
|
|
170
|
+
const labelled = edges.filter((edge) => hasPill(edge) && (!focus || focus.focused.has(edge.id)));
|
|
171
|
+
const points = Object.fromEntries(
|
|
172
|
+
labelled.map((edge) => [edge.id, labelPoint(edge, requireEntry(routes, edge.id, "route"), focus)])
|
|
173
|
+
);
|
|
174
|
+
const ys = spread ? labelYs(labelled, routes, points) : void 0;
|
|
175
|
+
return /* @__PURE__ */ jsx(Fragment, { children: labelled.map((edge) => {
|
|
176
|
+
const route = requireEntry(routes, edge.id, "route");
|
|
177
|
+
const point = requireEntry(points, edge.id, "label point");
|
|
178
|
+
return /* @__PURE__ */ jsxs(
|
|
179
|
+
"span",
|
|
180
|
+
{
|
|
181
|
+
"data-graph-edge-label": edge.id,
|
|
182
|
+
title: edge.title,
|
|
183
|
+
className: cn(
|
|
184
|
+
"absolute -translate-y-1/2 whitespace-nowrap rounded-full border border-border bg-background px-1.5 py-0.5 text-[10px] font-medium shadow-sm",
|
|
185
|
+
// A pill that only hover put there would take the pointer off what is hovered, and flicker.
|
|
186
|
+
focus && !focus.pinned.has(edge.id) ? "pointer-events-none" : "pointer-events-auto",
|
|
187
|
+
edge.icon != null && "flex items-center gap-1",
|
|
188
|
+
ANCHOR_CLASS[route.labelAnchor ?? "center"],
|
|
189
|
+
TONE_TEXT_CLASS[edge.tone ?? "neutral"],
|
|
190
|
+
onEdgeSelect && "cursor-pointer hover:bg-accent",
|
|
191
|
+
edge.id === selectedEdgeId && "border-primary ring-2 ring-primary/40"
|
|
192
|
+
),
|
|
193
|
+
style: place({ x: point.x, y: ys ? requireEntry(ys, edge.id, "label position") : point.y }),
|
|
194
|
+
...onEdgeSelect ? { "aria-hidden": true, onClick: () => onEdgeSelect(edge.id) } : {},
|
|
195
|
+
children: [
|
|
196
|
+
edge.icon != null && /* @__PURE__ */ jsx("span", { className: "flex shrink-0 text-sm leading-none", children: edge.icon }),
|
|
197
|
+
edge.label
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
`label-${edge.id}`
|
|
201
|
+
);
|
|
202
|
+
}) });
|
|
203
|
+
}
|
|
204
|
+
export {
|
|
205
|
+
GraphDiagramEdgeLabels,
|
|
206
|
+
GraphDiagramEdgePaths
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=GraphDiagramEdges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphDiagramEdges.js","sources":["../../src/data/GraphDiagramEdges.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { pointOnCurve, spreadLabels, type EdgeRoute } from \"./graph-edge-routing\";\nimport type { GraphLayoutPosition } from \"./graph-layout\";\nimport type { EdgeFocusState } from \"./use-edge-focus\";\nimport {\n activateOnKey,\n edgeLabelWidth,\n edgeName,\n hoverHandlers,\n nodeName,\n requireEntry,\n TONE_TEXT_CLASS,\n type GraphDiagramEdge,\n type GraphDiagramNode,\n type GraphPlacer,\n} from \"./graph-diagram-model\";\n\n// Arrowhead size in layout px. Fixed (userSpaceOnUse) so a thicker, selected\n// edge does not also grow its arrowhead.\nconst ARROW_SIZE = 10.5;\nconst EDGE_STROKE = 1.5;\nconst SELECTED_EDGE_STROKE = 2.75;\nconst HIT_STROKE = 14;\n\ninterface EdgeSelection {\n selectedEdgeId: string | undefined;\n onEdgeSelect: ((id: string) => void) | undefined;\n /** Set when the diagram is focused: see `GraphDiagramEdgeFocus`. */\n focus: EdgeFocusState | undefined;\n}\n\nexport interface GraphDiagramEdgePathsProps extends EdgeSelection {\n edges: GraphDiagramEdge[];\n nodes: GraphDiagramNode[];\n routes: Record<string, EdgeRoute>;\n width: number;\n height: number;\n ariaLabel: string;\n /** Unique per diagram instance, so two diagrams on a page never share marker ids. */\n markerPrefix: string;\n onEdgeHover: ((id: string | undefined) => void) | undefined;\n}\n\nfunction EdgePath({\n edge,\n d,\n markerId,\n name,\n selected,\n dimmed,\n onSelect,\n onHover,\n}: {\n edge: GraphDiagramEdge;\n d: string;\n markerId: string;\n name: string;\n selected: boolean;\n /** Out of focus while another edge is in it. */\n dimmed: boolean;\n onSelect: (() => void) | undefined;\n onHover: ((id: string | undefined) => void) | undefined;\n}) {\n return (\n <g\n data-graph-edge={edge.id}\n className={cn(\"transition-opacity\", dimmed && \"opacity-20\")}\n {...(dimmed ? { \"data-graph-edge-dimmed\": \"\" } : {})}\n {...(onHover ? hoverHandlers(edge.id, onHover) : {})}\n >\n {edge.title !== undefined && <title>{edge.title}</title>}\n <path\n d={d}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={selected ? SELECTED_EDGE_STROKE : EDGE_STROKE}\n strokeDasharray={edge.dashed ? \"5 4\" : undefined}\n pointerEvents=\"visibleStroke\"\n markerEnd={`url(#${markerId})`}\n className={TONE_TEXT_CLASS[edge.tone ?? \"neutral\"]}\n />\n {onSelect && (\n <path\n d={d}\n fill=\"none\"\n stroke=\"transparent\"\n strokeWidth={HIT_STROKE}\n strokeLinecap=\"round\"\n pointerEvents=\"stroke\"\n role=\"button\"\n tabIndex={0}\n aria-label={name}\n aria-pressed={selected}\n className={cn(\n \"cursor-pointer outline-none hover:stroke-primary/15 focus-visible:stroke-primary/30\",\n selected && \"stroke-primary/15\",\n )}\n onClick={onSelect}\n onKeyDown={(event) => activateOnKey(event, onSelect)}\n />\n )}\n </g>\n );\n}\n\nexport function GraphDiagramEdgePaths({\n edges,\n nodes,\n routes,\n width,\n height,\n ariaLabel,\n markerPrefix,\n selectedEdgeId,\n onEdgeSelect,\n focus,\n onEdgeHover,\n}: GraphDiagramEdgePathsProps) {\n const tones = Array.from(new Set(edges.map((edge) => edge.tone ?? \"neutral\")));\n const names = Object.fromEntries(nodes.map((node) => [node.id, nodeName(node)]));\n\n // The layer covers the whole stage, so it lets the pointer through: only an edge's own stroke\n // takes it, and the group captions under the layer keep their tooltips.\n return (\n <svg\n viewBox={`0 0 ${width} ${height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n role={onEdgeSelect ? \"group\" : \"img\"}\n aria-label={ariaLabel}\n className=\"pointer-events-none absolute inset-0 h-full w-full\"\n >\n <defs>\n {tones.map((tone) => (\n <marker\n key={tone}\n id={`${markerPrefix}-arrow-${tone}`}\n viewBox=\"0 0 10 10\"\n refX={8}\n refY={5}\n markerUnits=\"userSpaceOnUse\"\n markerWidth={ARROW_SIZE}\n markerHeight={ARROW_SIZE}\n orient=\"auto-start-reverse\"\n >\n <path d=\"M0,0 L10,5 L0,10 z\" className={cn(TONE_TEXT_CLASS[tone], \"fill-current\")} />\n </marker>\n ))}\n </defs>\n {edges.map((edge) => (\n <EdgePath\n key={edge.id}\n edge={edge}\n d={requireEntry(routes, edge.id, \"route\").path}\n markerId={`${markerPrefix}-arrow-${edge.tone ?? \"neutral\"}`}\n name={edgeName(edge, names)}\n selected={edge.id === selectedEdgeId}\n dimmed={focus !== undefined && focus.focused.size > 0 && !focus.focused.has(edge.id)}\n onSelect={onEdgeSelect ? () => onEdgeSelect(edge.id) : undefined}\n onHover={onEdgeHover}\n />\n ))}\n </svg>\n );\n}\n\nexport interface GraphDiagramEdgeLabelsProps extends EdgeSelection {\n edges: GraphDiagramEdge[];\n routes: Record<string, EdgeRoute>;\n place: GraphPlacer;\n /**\n * Move pills that would cover one another apart. Only meaningful when the\n * stage is drawn at its natural size, where a pill's px size and the layout\n * share one coordinate system.\n */\n spread: boolean;\n}\n\nconst LABEL_HEIGHT = 19;\n/** A loop's pill sits this far outside its point (the `translate-x` classes below). */\nconst LABEL_LOOP_GAP = 6;\n/** How far along its edge, from the node in focus, a pill sits: past the middle, where a fan has spread out. */\nconst FOCUS_LABEL_T = 0.65;\n/** Air kept between a slid pill and the nodes at either end of its edge. */\nconst LABEL_NODE_GAP = 4;\n\nconst ANCHOR_CLASS = {\n start: \"translate-x-1.5\",\n end: \"-translate-x-[calc(100%+0.375rem)]\",\n center: \"-translate-x-1/2\",\n} as const;\n\nfunction hasPill(edge: GraphDiagramEdge): boolean {\n return Boolean(edge.label) || edge.icon != null;\n}\n\n/**\n * Where an edge's pill is centred: the route's midpoint, unless exactly one\n * end of the edge is a node in focus. Then every pill of that node would sit\n * in one stack beside it, so each moves toward its own far end, kept between\n * the two nodes.\n */\nfunction labelPoint(edge: GraphDiagramEdge, route: EdgeRoute, focus: EdgeFocusState | undefined): GraphLayoutPosition {\n const middle = { x: route.labelX, y: route.labelY };\n if (!route.curve || !focus || focus.nodes.has(edge.from) === focus.nodes.has(edge.to)) return middle;\n const point = pointOnCurve(route.curve, focus.nodes.has(edge.from) ? FOCUS_LABEL_T : 1 - FOCUS_LABEL_T);\n const reserved = edgeLabelWidth(edge) / 2 + LABEL_NODE_GAP;\n const left = Math.min(route.curve[0].x, route.curve[3].x) + reserved;\n const right = Math.max(route.curve[0].x, route.curve[3].x) - reserved;\n return left > right ? { x: middle.x, y: point.y } : { x: Math.min(right, Math.max(left, point.x)), y: point.y };\n}\n\nfunction labelYs(\n edges: GraphDiagramEdge[],\n routes: Record<string, EdgeRoute>,\n points: Record<string, GraphLayoutPosition>,\n): Record<string, number> {\n return spreadLabels(\n edges.map((edge) => {\n const { labelAnchor } = requireEntry(routes, edge.id, \"route\");\n const point = requireEntry(points, edge.id, \"label point\");\n const outside = labelAnchor === undefined ? 0 : labelAnchor === \"start\" ? LABEL_LOOP_GAP : -LABEL_LOOP_GAP;\n return {\n id: edge.id,\n x: point.x + outside,\n y: point.y,\n width: edgeLabelWidth(edge),\n height: LABEL_HEIGHT,\n ...(labelAnchor ? { anchor: labelAnchor } : {}),\n };\n }),\n );\n}\n\n/**\n * The label pills, drawn as HTML over the edges. With `onEdgeSelect` a pill is\n * a pointer shortcut for its edge; the edge's own path stays the one\n * keyboard and screen-reader target, so the pill is hidden from both.\n */\nexport function GraphDiagramEdgeLabels({\n edges,\n routes,\n place,\n spread,\n selectedEdgeId,\n onEdgeSelect,\n focus,\n}: GraphDiagramEdgeLabelsProps) {\n const labelled = edges.filter((edge) => hasPill(edge) && (!focus || focus.focused.has(edge.id)));\n const points = Object.fromEntries(\n labelled.map((edge) => [edge.id, labelPoint(edge, requireEntry(routes, edge.id, \"route\"), focus)]),\n );\n const ys = spread ? labelYs(labelled, routes, points) : undefined;\n return (\n <>\n {labelled.map((edge) => {\n const route = requireEntry(routes, edge.id, \"route\");\n const point = requireEntry(points, edge.id, \"label point\");\n return (\n <span\n key={`label-${edge.id}`}\n data-graph-edge-label={edge.id}\n title={edge.title}\n className={cn(\n \"absolute -translate-y-1/2 whitespace-nowrap rounded-full border border-border bg-background px-1.5 py-0.5 text-[10px] font-medium shadow-sm\",\n // A pill that only hover put there would take the pointer off what is hovered, and flicker.\n focus && !focus.pinned.has(edge.id) ? \"pointer-events-none\" : \"pointer-events-auto\",\n edge.icon != null && \"flex items-center gap-1\",\n ANCHOR_CLASS[route.labelAnchor ?? \"center\"],\n TONE_TEXT_CLASS[edge.tone ?? \"neutral\"],\n onEdgeSelect && \"cursor-pointer hover:bg-accent\",\n edge.id === selectedEdgeId && \"border-primary ring-2 ring-primary/40\",\n )}\n style={place({ x: point.x, y: ys ? requireEntry(ys, edge.id, \"label position\") : point.y })}\n {...(onEdgeSelect\n ? { \"aria-hidden\": true, onClick: () => onEdgeSelect(edge.id) }\n : {})}\n >\n {edge.icon != null && <span className=\"flex shrink-0 text-sm leading-none\">{edge.icon}</span>}\n {edge.label}\n </span>\n );\n })}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const utils = require("../lib/utils.cjs");
|
|
5
|
+
const graphDiagramModel = require("./graph-diagram-model.cjs");
|
|
6
|
+
const EXPAND_CLASS = "absolute bottom-0 translate-y-1/2 rounded-full border border-border bg-background px-1.5 text-[10px] font-semibold leading-4 text-muted-foreground shadow-sm";
|
|
7
|
+
function ExpandControl({ node, onExpand }) {
|
|
8
|
+
const side = (node.level ?? 0) < 0 ? "left-2" : "right-2";
|
|
9
|
+
const text = `+${node.expandCount}`;
|
|
10
|
+
if (!onExpand) {
|
|
11
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn(EXPAND_CLASS, side), children: text });
|
|
12
|
+
}
|
|
13
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
14
|
+
"button",
|
|
15
|
+
{
|
|
16
|
+
type: "button",
|
|
17
|
+
"aria-label": `Expand ${node.expandCount} more from ${graphDiagramModel.nodeName(node)}`,
|
|
18
|
+
className: utils.cn(
|
|
19
|
+
EXPAND_CLASS,
|
|
20
|
+
side,
|
|
21
|
+
"cursor-pointer hover:border-primary hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
22
|
+
),
|
|
23
|
+
onClick: onExpand,
|
|
24
|
+
children: text
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
const TWO_LINE_HEIGHT = 44;
|
|
29
|
+
function NodeLabel({ node, oneLine }) {
|
|
30
|
+
const label = /* @__PURE__ */ jsxRuntime.jsx(
|
|
31
|
+
"span",
|
|
32
|
+
{
|
|
33
|
+
className: utils.cn(
|
|
34
|
+
oneLine ? "max-w-full truncate" : "line-clamp-2",
|
|
35
|
+
"font-medium leading-tight",
|
|
36
|
+
node.icon != null && "min-w-0"
|
|
37
|
+
),
|
|
38
|
+
children: node.label
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
if (node.icon == null) return label;
|
|
42
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex max-w-full items-center gap-1.5", children: [
|
|
43
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-graph-node-icon": "", className: "flex shrink-0 text-base leading-none", children: node.icon }),
|
|
44
|
+
label
|
|
45
|
+
] });
|
|
46
|
+
}
|
|
47
|
+
function NodeBody({
|
|
48
|
+
node,
|
|
49
|
+
oneLine,
|
|
50
|
+
selected,
|
|
51
|
+
onSelect
|
|
52
|
+
}) {
|
|
53
|
+
const tone = node.tone ?? "neutral";
|
|
54
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
55
|
+
"div",
|
|
56
|
+
{
|
|
57
|
+
className: utils.cn(
|
|
58
|
+
"flex h-full w-full flex-col items-center justify-center gap-0.5 border px-3 py-1.5 text-center text-xs shadow-sm",
|
|
59
|
+
node.shape === "pill" ? "rounded-full" : "rounded-lg",
|
|
60
|
+
graphDiagramModel.TONE_NODE_CLASS[tone],
|
|
61
|
+
node.muted && "border-dashed text-muted-foreground shadow-none",
|
|
62
|
+
node.muted && tone === "neutral" && "bg-muted",
|
|
63
|
+
selected && "ring-2 ring-primary ring-offset-2 ring-offset-background",
|
|
64
|
+
onSelect && "cursor-pointer"
|
|
65
|
+
),
|
|
66
|
+
...onSelect ? {
|
|
67
|
+
role: "button",
|
|
68
|
+
tabIndex: 0,
|
|
69
|
+
"aria-pressed": selected,
|
|
70
|
+
onClick: onSelect,
|
|
71
|
+
onKeyDown: (event) => graphDiagramModel.activateOnKey(event, onSelect)
|
|
72
|
+
} : {},
|
|
73
|
+
"aria-label": node.ariaLabel,
|
|
74
|
+
title: node.title,
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx(NodeLabel, { node, oneLine }),
|
|
77
|
+
node.detail != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1 text-[10px] leading-tight text-muted-foreground", children: node.detail }),
|
|
78
|
+
node.badge != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5", children: node.badge })
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function GraphDiagramNodes({
|
|
84
|
+
nodes,
|
|
85
|
+
positions,
|
|
86
|
+
place,
|
|
87
|
+
nodeWidth,
|
|
88
|
+
nodeHeight,
|
|
89
|
+
selectedId,
|
|
90
|
+
onNodeSelect,
|
|
91
|
+
onNodeExpand,
|
|
92
|
+
onNodeHover
|
|
93
|
+
}) {
|
|
94
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: nodes.map((node) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
95
|
+
"div",
|
|
96
|
+
{
|
|
97
|
+
"data-graph-node": node.id,
|
|
98
|
+
className: "pointer-events-auto absolute -translate-x-1/2 -translate-y-1/2",
|
|
99
|
+
style: { ...place(graphDiagramModel.requireEntry(positions, node.id, "layout position")), width: nodeWidth, height: nodeHeight },
|
|
100
|
+
...onNodeHover ? graphDiagramModel.hoverHandlers(node.id, onNodeHover) : {},
|
|
101
|
+
children: [
|
|
102
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
103
|
+
NodeBody,
|
|
104
|
+
{
|
|
105
|
+
node,
|
|
106
|
+
oneLine: nodeHeight < TWO_LINE_HEIGHT,
|
|
107
|
+
selected: selectedId != null && node.id === selectedId,
|
|
108
|
+
onSelect: onNodeSelect ? () => onNodeSelect(node.id) : void 0
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
node.expandCount != null && node.expandCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(ExpandControl, { node, onExpand: onNodeExpand ? () => onNodeExpand(node.id) : void 0 })
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
node.id
|
|
115
|
+
)) });
|
|
116
|
+
}
|
|
117
|
+
function GraphDiagramGroupBoxes({ boxes, groups }) {
|
|
118
|
+
const captions = new Map(groups == null ? void 0 : groups.map((group) => [group.id, group]));
|
|
119
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: boxes.map((box) => {
|
|
120
|
+
const caption = captions.get(box.group);
|
|
121
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
122
|
+
"div",
|
|
123
|
+
{
|
|
124
|
+
"data-graph-group": box.id,
|
|
125
|
+
className: "absolute rounded-xl border border-dashed border-border bg-muted/30",
|
|
126
|
+
style: { left: box.x, top: box.y, width: box.width, height: box.height },
|
|
127
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
128
|
+
"span",
|
|
129
|
+
{
|
|
130
|
+
title: caption == null ? void 0 : caption.title,
|
|
131
|
+
className: "absolute left-2 top-0 max-w-[calc(100%-1rem)] -translate-y-1/2 truncate rounded border border-border bg-background px-1.5 text-[10px] font-medium leading-4 text-muted-foreground",
|
|
132
|
+
children: caption ? caption.label : box.group
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
},
|
|
136
|
+
box.id
|
|
137
|
+
);
|
|
138
|
+
}) });
|
|
139
|
+
}
|
|
140
|
+
exports.GraphDiagramGroupBoxes = GraphDiagramGroupBoxes;
|
|
141
|
+
exports.GraphDiagramNodes = GraphDiagramNodes;
|
|
142
|
+
//# sourceMappingURL=GraphDiagramNodes.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphDiagramNodes.cjs","sources":["../../src/data/GraphDiagramNodes.tsx"],"sourcesContent":["import type { KeyboardEvent } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport type { GraphLayoutPosition } from \"./graph-layout\";\nimport type { GraphLayoutGroupBox } from \"./graph-columns-layout\";\nimport {\n activateOnKey,\n hoverHandlers,\n nodeName,\n requireEntry,\n TONE_NODE_CLASS,\n type GraphDiagramGroup,\n type GraphDiagramNode,\n type GraphPlacer,\n} from \"./graph-diagram-model\";\n\nexport interface GraphDiagramNodesProps {\n nodes: GraphDiagramNode[];\n positions: Record<string, GraphLayoutPosition>;\n place: GraphPlacer;\n nodeWidth: number;\n nodeHeight: number;\n selectedId: string | undefined;\n onNodeSelect: ((id: string) => void) | undefined;\n onNodeExpand: ((id: string) => void) | undefined;\n onNodeHover: ((id: string | undefined) => void) | undefined;\n}\n\nconst EXPAND_CLASS =\n \"absolute bottom-0 translate-y-1/2 rounded-full border border-border bg-background px-1.5 text-[10px] font-semibold leading-4 text-muted-foreground shadow-sm\";\n\n/**\n * The `+N` control. It hangs off the node's bottom edge at its outer end —\n * the left for a node left of level 0, the right otherwise — which keeps it\n * clear of the side middles where edges attach. It is a sibling of the node,\n * not a child, so activating it never also selects the node.\n */\nfunction ExpandControl({ node, onExpand }: { node: GraphDiagramNode; onExpand: (() => void) | undefined }) {\n const side = (node.level ?? 0) < 0 ? \"left-2\" : \"right-2\";\n const text = `+${node.expandCount}`;\n if (!onExpand) {\n return <span className={cn(EXPAND_CLASS, side)}>{text}</span>;\n }\n return (\n <button\n type=\"button\"\n aria-label={`Expand ${node.expandCount} more from ${nodeName(node)}`}\n className={cn(\n EXPAND_CLASS,\n side,\n \"cursor-pointer hover:border-primary hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n )}\n onClick={onExpand}\n >\n {text}\n </button>\n );\n}\n\n// Two 15px label lines, the body's vertical padding and its border.\nconst TWO_LINE_HEIGHT = 44;\n\n/** The label, behind the node's icon when it has one. `oneLine` cuts it with an ellipsis instead of wrapping. */\nfunction NodeLabel({ node, oneLine }: { node: GraphDiagramNode; oneLine: boolean }) {\n const label = (\n <span\n className={cn(\n oneLine ? \"max-w-full truncate\" : \"line-clamp-2\",\n \"font-medium leading-tight\",\n node.icon != null && \"min-w-0\",\n )}\n >\n {node.label}\n </span>\n );\n if (node.icon == null) return label;\n return (\n <span className=\"flex max-w-full items-center gap-1.5\">\n <span data-graph-node-icon=\"\" className=\"flex shrink-0 text-base leading-none\">\n {node.icon}\n </span>\n {label}\n </span>\n );\n}\n\nfunction NodeBody({\n node,\n oneLine,\n selected,\n onSelect,\n}: {\n node: GraphDiagramNode;\n /** The node is too short for two label lines. */\n oneLine: boolean;\n selected: boolean;\n onSelect: (() => void) | undefined;\n}) {\n const tone = node.tone ?? \"neutral\";\n return (\n <div\n className={cn(\n \"flex h-full w-full flex-col items-center justify-center gap-0.5 border px-3 py-1.5 text-center text-xs shadow-sm\",\n node.shape === \"pill\" ? \"rounded-full\" : \"rounded-lg\",\n TONE_NODE_CLASS[tone],\n node.muted && \"border-dashed text-muted-foreground shadow-none\",\n node.muted && tone === \"neutral\" && \"bg-muted\",\n selected && \"ring-2 ring-primary ring-offset-2 ring-offset-background\",\n onSelect && \"cursor-pointer\",\n )}\n {...(onSelect\n ? {\n role: \"button\" as const,\n tabIndex: 0,\n \"aria-pressed\": selected,\n onClick: onSelect,\n onKeyDown: (event: KeyboardEvent<HTMLDivElement>) => activateOnKey(event, onSelect),\n }\n : {})}\n aria-label={node.ariaLabel}\n title={node.title}\n >\n <NodeLabel node={node} oneLine={oneLine} />\n {node.detail != null && (\n <span className=\"line-clamp-1 text-[10px] leading-tight text-muted-foreground\">{node.detail}</span>\n )}\n {node.badge != null && <span className=\"mt-0.5\">{node.badge}</span>}\n </div>\n );\n}\n\nexport function GraphDiagramNodes({\n nodes,\n positions,\n place,\n nodeWidth,\n nodeHeight,\n selectedId,\n onNodeSelect,\n onNodeExpand,\n onNodeHover,\n}: GraphDiagramNodesProps) {\n return (\n <>\n {nodes.map((node) => (\n <div\n key={node.id}\n data-graph-node={node.id}\n className=\"pointer-events-auto absolute -translate-x-1/2 -translate-y-1/2\"\n style={{ ...place(requireEntry(positions, node.id, \"layout position\")), width: nodeWidth, height: nodeHeight }}\n {...(onNodeHover ? hoverHandlers(node.id, onNodeHover) : {})}\n >\n <NodeBody\n node={node}\n oneLine={nodeHeight < TWO_LINE_HEIGHT}\n selected={selectedId != null && node.id === selectedId}\n onSelect={onNodeSelect ? () => onNodeSelect(node.id) : undefined}\n />\n {node.expandCount != null && node.expandCount > 0 && (\n <ExpandControl node={node} onExpand={onNodeExpand ? () => onNodeExpand(node.id) : undefined} />\n )}\n </div>\n ))}\n </>\n );\n}\n\nexport interface GraphDiagramGroupBoxesProps {\n boxes: GraphLayoutGroupBox[];\n groups: GraphDiagramGroup[] | undefined;\n}\n\n/** Group rectangles, drawn behind the edges and nodes, each captioned on its top border. */\nexport function GraphDiagramGroupBoxes({ boxes, groups }: GraphDiagramGroupBoxesProps) {\n const captions = new Map(groups?.map((group) => [group.id, group]));\n return (\n <>\n {boxes.map((box) => {\n const caption = captions.get(box.group);\n return (\n <div\n key={box.id}\n data-graph-group={box.id}\n className=\"absolute rounded-xl border border-dashed border-border bg-muted/30\"\n style={{ left: box.x, top: box.y, width: box.width, height: box.height }}\n >\n <span\n title={caption?.title}\n className=\"absolute left-2 top-0 max-w-[calc(100%-1rem)] -translate-y-1/2 truncate rounded border border-border bg-background px-1.5 text-[10px] font-medium leading-4 text-muted-foreground\"\n >\n {caption ? caption.label : box.group}\n </span>\n </div>\n );\n })}\n </>\n );\n}\n"],"names":["cn","jsx","nodeName","jsxs","TONE_NODE_CLASS","activateOnKey","Fragment","requireEntry","hoverHandlers"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GraphLayoutPosition } from './graph-layout.js';
|
|
2
|
+
import { GraphLayoutGroupBox } from './graph-columns-layout.js';
|
|
3
|
+
import { GraphDiagramGroup, GraphDiagramNode, GraphPlacer } from './graph-diagram-model.js';
|
|
4
|
+
export interface GraphDiagramNodesProps {
|
|
5
|
+
nodes: GraphDiagramNode[];
|
|
6
|
+
positions: Record<string, GraphLayoutPosition>;
|
|
7
|
+
place: GraphPlacer;
|
|
8
|
+
nodeWidth: number;
|
|
9
|
+
nodeHeight: number;
|
|
10
|
+
selectedId: string | undefined;
|
|
11
|
+
onNodeSelect: ((id: string) => void) | undefined;
|
|
12
|
+
onNodeExpand: ((id: string) => void) | undefined;
|
|
13
|
+
onNodeHover: ((id: string | undefined) => void) | undefined;
|
|
14
|
+
}
|
|
15
|
+
export declare function GraphDiagramNodes({ nodes, positions, place, nodeWidth, nodeHeight, selectedId, onNodeSelect, onNodeExpand, onNodeHover, }: GraphDiagramNodesProps): import("react").JSX.Element;
|
|
16
|
+
export interface GraphDiagramGroupBoxesProps {
|
|
17
|
+
boxes: GraphLayoutGroupBox[];
|
|
18
|
+
groups: GraphDiagramGroup[] | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Group rectangles, drawn behind the edges and nodes, each captioned on its top border. */
|
|
21
|
+
export declare function GraphDiagramGroupBoxes({ boxes, groups }: GraphDiagramGroupBoxesProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=GraphDiagramNodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphDiagramNodes.d.ts","sourceRoot":"","sources":["../../src/data/GraphDiagramNodes.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAML,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC/C,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACjD,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACjD,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7D;AAyGD,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,SAAS,EACT,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,EAAE,sBAAsB,+BAwBxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,MAAM,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;CACzC;AAED,4FAA4F;AAC5F,wBAAgB,sBAAsB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,2BAA2B,+BAwBpF"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { hoverHandlers, requireEntry, activateOnKey, TONE_NODE_CLASS, nodeName } from "./graph-diagram-model.js";
|
|
4
|
+
const EXPAND_CLASS = "absolute bottom-0 translate-y-1/2 rounded-full border border-border bg-background px-1.5 text-[10px] font-semibold leading-4 text-muted-foreground shadow-sm";
|
|
5
|
+
function ExpandControl({ node, onExpand }) {
|
|
6
|
+
const side = (node.level ?? 0) < 0 ? "left-2" : "right-2";
|
|
7
|
+
const text = `+${node.expandCount}`;
|
|
8
|
+
if (!onExpand) {
|
|
9
|
+
return /* @__PURE__ */ jsx("span", { className: cn(EXPAND_CLASS, side), children: text });
|
|
10
|
+
}
|
|
11
|
+
return /* @__PURE__ */ jsx(
|
|
12
|
+
"button",
|
|
13
|
+
{
|
|
14
|
+
type: "button",
|
|
15
|
+
"aria-label": `Expand ${node.expandCount} more from ${nodeName(node)}`,
|
|
16
|
+
className: cn(
|
|
17
|
+
EXPAND_CLASS,
|
|
18
|
+
side,
|
|
19
|
+
"cursor-pointer hover:border-primary hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
20
|
+
),
|
|
21
|
+
onClick: onExpand,
|
|
22
|
+
children: text
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
const TWO_LINE_HEIGHT = 44;
|
|
27
|
+
function NodeLabel({ node, oneLine }) {
|
|
28
|
+
const label = /* @__PURE__ */ jsx(
|
|
29
|
+
"span",
|
|
30
|
+
{
|
|
31
|
+
className: cn(
|
|
32
|
+
oneLine ? "max-w-full truncate" : "line-clamp-2",
|
|
33
|
+
"font-medium leading-tight",
|
|
34
|
+
node.icon != null && "min-w-0"
|
|
35
|
+
),
|
|
36
|
+
children: node.label
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
if (node.icon == null) return label;
|
|
40
|
+
return /* @__PURE__ */ jsxs("span", { className: "flex max-w-full items-center gap-1.5", children: [
|
|
41
|
+
/* @__PURE__ */ jsx("span", { "data-graph-node-icon": "", className: "flex shrink-0 text-base leading-none", children: node.icon }),
|
|
42
|
+
label
|
|
43
|
+
] });
|
|
44
|
+
}
|
|
45
|
+
function NodeBody({
|
|
46
|
+
node,
|
|
47
|
+
oneLine,
|
|
48
|
+
selected,
|
|
49
|
+
onSelect
|
|
50
|
+
}) {
|
|
51
|
+
const tone = node.tone ?? "neutral";
|
|
52
|
+
return /* @__PURE__ */ jsxs(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
className: cn(
|
|
56
|
+
"flex h-full w-full flex-col items-center justify-center gap-0.5 border px-3 py-1.5 text-center text-xs shadow-sm",
|
|
57
|
+
node.shape === "pill" ? "rounded-full" : "rounded-lg",
|
|
58
|
+
TONE_NODE_CLASS[tone],
|
|
59
|
+
node.muted && "border-dashed text-muted-foreground shadow-none",
|
|
60
|
+
node.muted && tone === "neutral" && "bg-muted",
|
|
61
|
+
selected && "ring-2 ring-primary ring-offset-2 ring-offset-background",
|
|
62
|
+
onSelect && "cursor-pointer"
|
|
63
|
+
),
|
|
64
|
+
...onSelect ? {
|
|
65
|
+
role: "button",
|
|
66
|
+
tabIndex: 0,
|
|
67
|
+
"aria-pressed": selected,
|
|
68
|
+
onClick: onSelect,
|
|
69
|
+
onKeyDown: (event) => activateOnKey(event, onSelect)
|
|
70
|
+
} : {},
|
|
71
|
+
"aria-label": node.ariaLabel,
|
|
72
|
+
title: node.title,
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ jsx(NodeLabel, { node, oneLine }),
|
|
75
|
+
node.detail != null && /* @__PURE__ */ jsx("span", { className: "line-clamp-1 text-[10px] leading-tight text-muted-foreground", children: node.detail }),
|
|
76
|
+
node.badge != null && /* @__PURE__ */ jsx("span", { className: "mt-0.5", children: node.badge })
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
function GraphDiagramNodes({
|
|
82
|
+
nodes,
|
|
83
|
+
positions,
|
|
84
|
+
place,
|
|
85
|
+
nodeWidth,
|
|
86
|
+
nodeHeight,
|
|
87
|
+
selectedId,
|
|
88
|
+
onNodeSelect,
|
|
89
|
+
onNodeExpand,
|
|
90
|
+
onNodeHover
|
|
91
|
+
}) {
|
|
92
|
+
return /* @__PURE__ */ jsx(Fragment, { children: nodes.map((node) => /* @__PURE__ */ jsxs(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
"data-graph-node": node.id,
|
|
96
|
+
className: "pointer-events-auto absolute -translate-x-1/2 -translate-y-1/2",
|
|
97
|
+
style: { ...place(requireEntry(positions, node.id, "layout position")), width: nodeWidth, height: nodeHeight },
|
|
98
|
+
...onNodeHover ? hoverHandlers(node.id, onNodeHover) : {},
|
|
99
|
+
children: [
|
|
100
|
+
/* @__PURE__ */ jsx(
|
|
101
|
+
NodeBody,
|
|
102
|
+
{
|
|
103
|
+
node,
|
|
104
|
+
oneLine: nodeHeight < TWO_LINE_HEIGHT,
|
|
105
|
+
selected: selectedId != null && node.id === selectedId,
|
|
106
|
+
onSelect: onNodeSelect ? () => onNodeSelect(node.id) : void 0
|
|
107
|
+
}
|
|
108
|
+
),
|
|
109
|
+
node.expandCount != null && node.expandCount > 0 && /* @__PURE__ */ jsx(ExpandControl, { node, onExpand: onNodeExpand ? () => onNodeExpand(node.id) : void 0 })
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
node.id
|
|
113
|
+
)) });
|
|
114
|
+
}
|
|
115
|
+
function GraphDiagramGroupBoxes({ boxes, groups }) {
|
|
116
|
+
const captions = new Map(groups == null ? void 0 : groups.map((group) => [group.id, group]));
|
|
117
|
+
return /* @__PURE__ */ jsx(Fragment, { children: boxes.map((box) => {
|
|
118
|
+
const caption = captions.get(box.group);
|
|
119
|
+
return /* @__PURE__ */ jsx(
|
|
120
|
+
"div",
|
|
121
|
+
{
|
|
122
|
+
"data-graph-group": box.id,
|
|
123
|
+
className: "absolute rounded-xl border border-dashed border-border bg-muted/30",
|
|
124
|
+
style: { left: box.x, top: box.y, width: box.width, height: box.height },
|
|
125
|
+
children: /* @__PURE__ */ jsx(
|
|
126
|
+
"span",
|
|
127
|
+
{
|
|
128
|
+
title: caption == null ? void 0 : caption.title,
|
|
129
|
+
className: "absolute left-2 top-0 max-w-[calc(100%-1rem)] -translate-y-1/2 truncate rounded border border-border bg-background px-1.5 text-[10px] font-medium leading-4 text-muted-foreground",
|
|
130
|
+
children: caption ? caption.label : box.group
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
},
|
|
134
|
+
box.id
|
|
135
|
+
);
|
|
136
|
+
}) });
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
GraphDiagramGroupBoxes,
|
|
140
|
+
GraphDiagramNodes
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=GraphDiagramNodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphDiagramNodes.js","sources":["../../src/data/GraphDiagramNodes.tsx"],"sourcesContent":["import type { KeyboardEvent } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport type { GraphLayoutPosition } from \"./graph-layout\";\nimport type { GraphLayoutGroupBox } from \"./graph-columns-layout\";\nimport {\n activateOnKey,\n hoverHandlers,\n nodeName,\n requireEntry,\n TONE_NODE_CLASS,\n type GraphDiagramGroup,\n type GraphDiagramNode,\n type GraphPlacer,\n} from \"./graph-diagram-model\";\n\nexport interface GraphDiagramNodesProps {\n nodes: GraphDiagramNode[];\n positions: Record<string, GraphLayoutPosition>;\n place: GraphPlacer;\n nodeWidth: number;\n nodeHeight: number;\n selectedId: string | undefined;\n onNodeSelect: ((id: string) => void) | undefined;\n onNodeExpand: ((id: string) => void) | undefined;\n onNodeHover: ((id: string | undefined) => void) | undefined;\n}\n\nconst EXPAND_CLASS =\n \"absolute bottom-0 translate-y-1/2 rounded-full border border-border bg-background px-1.5 text-[10px] font-semibold leading-4 text-muted-foreground shadow-sm\";\n\n/**\n * The `+N` control. It hangs off the node's bottom edge at its outer end —\n * the left for a node left of level 0, the right otherwise — which keeps it\n * clear of the side middles where edges attach. It is a sibling of the node,\n * not a child, so activating it never also selects the node.\n */\nfunction ExpandControl({ node, onExpand }: { node: GraphDiagramNode; onExpand: (() => void) | undefined }) {\n const side = (node.level ?? 0) < 0 ? \"left-2\" : \"right-2\";\n const text = `+${node.expandCount}`;\n if (!onExpand) {\n return <span className={cn(EXPAND_CLASS, side)}>{text}</span>;\n }\n return (\n <button\n type=\"button\"\n aria-label={`Expand ${node.expandCount} more from ${nodeName(node)}`}\n className={cn(\n EXPAND_CLASS,\n side,\n \"cursor-pointer hover:border-primary hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n )}\n onClick={onExpand}\n >\n {text}\n </button>\n );\n}\n\n// Two 15px label lines, the body's vertical padding and its border.\nconst TWO_LINE_HEIGHT = 44;\n\n/** The label, behind the node's icon when it has one. `oneLine` cuts it with an ellipsis instead of wrapping. */\nfunction NodeLabel({ node, oneLine }: { node: GraphDiagramNode; oneLine: boolean }) {\n const label = (\n <span\n className={cn(\n oneLine ? \"max-w-full truncate\" : \"line-clamp-2\",\n \"font-medium leading-tight\",\n node.icon != null && \"min-w-0\",\n )}\n >\n {node.label}\n </span>\n );\n if (node.icon == null) return label;\n return (\n <span className=\"flex max-w-full items-center gap-1.5\">\n <span data-graph-node-icon=\"\" className=\"flex shrink-0 text-base leading-none\">\n {node.icon}\n </span>\n {label}\n </span>\n );\n}\n\nfunction NodeBody({\n node,\n oneLine,\n selected,\n onSelect,\n}: {\n node: GraphDiagramNode;\n /** The node is too short for two label lines. */\n oneLine: boolean;\n selected: boolean;\n onSelect: (() => void) | undefined;\n}) {\n const tone = node.tone ?? \"neutral\";\n return (\n <div\n className={cn(\n \"flex h-full w-full flex-col items-center justify-center gap-0.5 border px-3 py-1.5 text-center text-xs shadow-sm\",\n node.shape === \"pill\" ? \"rounded-full\" : \"rounded-lg\",\n TONE_NODE_CLASS[tone],\n node.muted && \"border-dashed text-muted-foreground shadow-none\",\n node.muted && tone === \"neutral\" && \"bg-muted\",\n selected && \"ring-2 ring-primary ring-offset-2 ring-offset-background\",\n onSelect && \"cursor-pointer\",\n )}\n {...(onSelect\n ? {\n role: \"button\" as const,\n tabIndex: 0,\n \"aria-pressed\": selected,\n onClick: onSelect,\n onKeyDown: (event: KeyboardEvent<HTMLDivElement>) => activateOnKey(event, onSelect),\n }\n : {})}\n aria-label={node.ariaLabel}\n title={node.title}\n >\n <NodeLabel node={node} oneLine={oneLine} />\n {node.detail != null && (\n <span className=\"line-clamp-1 text-[10px] leading-tight text-muted-foreground\">{node.detail}</span>\n )}\n {node.badge != null && <span className=\"mt-0.5\">{node.badge}</span>}\n </div>\n );\n}\n\nexport function GraphDiagramNodes({\n nodes,\n positions,\n place,\n nodeWidth,\n nodeHeight,\n selectedId,\n onNodeSelect,\n onNodeExpand,\n onNodeHover,\n}: GraphDiagramNodesProps) {\n return (\n <>\n {nodes.map((node) => (\n <div\n key={node.id}\n data-graph-node={node.id}\n className=\"pointer-events-auto absolute -translate-x-1/2 -translate-y-1/2\"\n style={{ ...place(requireEntry(positions, node.id, \"layout position\")), width: nodeWidth, height: nodeHeight }}\n {...(onNodeHover ? hoverHandlers(node.id, onNodeHover) : {})}\n >\n <NodeBody\n node={node}\n oneLine={nodeHeight < TWO_LINE_HEIGHT}\n selected={selectedId != null && node.id === selectedId}\n onSelect={onNodeSelect ? () => onNodeSelect(node.id) : undefined}\n />\n {node.expandCount != null && node.expandCount > 0 && (\n <ExpandControl node={node} onExpand={onNodeExpand ? () => onNodeExpand(node.id) : undefined} />\n )}\n </div>\n ))}\n </>\n );\n}\n\nexport interface GraphDiagramGroupBoxesProps {\n boxes: GraphLayoutGroupBox[];\n groups: GraphDiagramGroup[] | undefined;\n}\n\n/** Group rectangles, drawn behind the edges and nodes, each captioned on its top border. */\nexport function GraphDiagramGroupBoxes({ boxes, groups }: GraphDiagramGroupBoxesProps) {\n const captions = new Map(groups?.map((group) => [group.id, group]));\n return (\n <>\n {boxes.map((box) => {\n const caption = captions.get(box.group);\n return (\n <div\n key={box.id}\n data-graph-group={box.id}\n className=\"absolute rounded-xl border border-dashed border-border bg-muted/30\"\n style={{ left: box.x, top: box.y, width: box.width, height: box.height }}\n >\n <span\n title={caption?.title}\n className=\"absolute left-2 top-0 max-w-[calc(100%-1rem)] -translate-y-1/2 truncate rounded border border-border bg-background px-1.5 text-[10px] font-medium leading-4 text-muted-foreground\"\n >\n {caption ? caption.label : box.group}\n </span>\n </div>\n );\n })}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|