@ankhorage/zora 22.1.3 → 23.0.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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.d.ts +2 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.js +2 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.js +12 -4
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts +2 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js +3 -3
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js.map +1 -1
- package/dist/features/selection/adapters/inbound/SelectableItem.d.ts +1 -5
- package/dist/features/selection/adapters/inbound/SelectableItem.d.ts.map +1 -1
- package/dist/features/selection/adapters/inbound/SelectableItem.js +30 -54
- package/dist/features/selection/adapters/inbound/SelectableItem.js.map +1 -1
- package/dist/features/selection/adapters/inbound/SelectionProvider.d.ts +2 -6
- package/dist/features/selection/adapters/inbound/SelectionProvider.d.ts.map +1 -1
- package/dist/features/selection/adapters/inbound/SelectionProvider.js +36 -32
- package/dist/features/selection/adapters/inbound/SelectionProvider.js.map +1 -1
- package/dist/features/selection/application/resolveSelectionEventIntent.d.ts +5 -0
- package/dist/features/selection/application/resolveSelectionEventIntent.d.ts.map +1 -0
- package/dist/features/selection/application/resolveSelectionEventIntent.js +49 -0
- package/dist/features/selection/application/resolveSelectionEventIntent.js.map +1 -0
- package/dist/features/selection/public.d.ts +2 -0
- package/dist/features/selection/public.d.ts.map +1 -1
- package/dist/features/selection/public.js +1 -0
- package/dist/features/selection/public.js.map +1 -1
- package/dist/features/selection/utils/resolveSelectionNextIds.d.ts +4 -5
- package/dist/features/selection/utils/resolveSelectionNextIds.d.ts.map +1 -1
- package/dist/features/selection/utils/resolveSelectionNextIds.js +6 -13
- package/dist/features/selection/utils/resolveSelectionNextIds.js.map +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeItem.d.ts +3 -2
- package/dist/features/tree-view/adapters/inbound/TreeItem.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeItem.js +11 -4
- package/dist/features/tree-view/adapters/inbound/TreeItem.js.map +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeView.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeView.js +4 -5
- package/dist/features/tree-view/adapters/inbound/TreeView.js.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.d.ts +3 -2
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.js +17 -9
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.js.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.d.ts +4 -3
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.js +8 -8
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/graph-view.d.ts +2 -0
- package/dist/types/graph-view.d.ts.map +1 -1
- package/dist/types/graph-view.js.map +1 -1
- package/dist/types/selection.d.ts +3 -0
- package/dist/types/selection.d.ts.map +1 -1
- package/dist/types/selection.js.map +1 -1
- package/dist/types/tree-view.d.ts +3 -2
- package/dist/types/tree-view.d.ts.map +1 -1
- package/dist/types/tree-view.js.map +1 -1
- package/package.json +4 -4
- package/src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx +10 -2
- package/src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx +3 -1
- package/src/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.ts +22 -5
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.test.ts +21 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts +10 -3
- package/src/features/selection/adapters/inbound/SelectableItem.tsx +33 -50
- package/src/features/selection/adapters/inbound/SelectionProvider.tsx +34 -35
- package/src/features/selection/application/resolveSelectionEventIntent.test.ts +35 -0
- package/src/features/selection/application/resolveSelectionEventIntent.ts +55 -0
- package/src/features/selection/public.ts +2 -0
- package/src/features/selection/utils/resolveSelectionNextIds.test.ts +1 -14
- package/src/features/selection/utils/resolveSelectionNextIds.ts +6 -28
- package/src/features/tree-view/adapters/inbound/TreeItem.tsx +25 -9
- package/src/features/tree-view/adapters/inbound/TreeView.tsx +4 -6
- package/src/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.tsx +26 -8
- package/src/features/tree-view/adapters/inbound/web-artifact/TreeView.test.tsx +77 -7
- package/src/features/tree-view/adapters/inbound/web-artifact/TreeView.tsx +11 -9
- package/src/index.ts +1 -0
- package/src/types/graph-view.ts +2 -0
- package/src/types/selection.ts +3 -0
- package/src/types/tree-view.ts +3 -2
- package/web-dist/chunks/{Accordion-j2aw3d5b.js → Accordion-01e56hb5.js} +1 -1
- package/web-dist/chunks/{Accordion-emczc5rg.js → Accordion-09se459d.js} +4 -4
- package/web-dist/chunks/{Accordion-784f23tq.js → Accordion-14p7zanv.js} +1 -1
- package/web-dist/chunks/{Accordion-cecn51ry.js → Accordion-17pht8jd.js} +3 -3
- package/web-dist/chunks/Accordion-5df6cgyf.js +55 -0
- package/web-dist/chunks/{Accordion-sr353w95.js → Accordion-78mj69zp.js} +2 -2
- package/web-dist/chunks/{Accordion-mpnb4qqw.js → Accordion-83hfn3y4.js} +5 -5
- package/web-dist/chunks/{Accordion-07rdw2vh.js → Accordion-89q14src.js} +2 -2
- package/web-dist/chunks/{Accordion-ajydqhjp.js → Accordion-8xk2zmr5.js} +2 -2
- package/web-dist/chunks/{Accordion-qvt6qdqm.js → Accordion-b3ymabze.js} +4 -4
- package/web-dist/chunks/{Accordion-avmgvcef.js → Accordion-cn8tbdvk.js} +3 -3
- package/web-dist/chunks/{Accordion-8af800ts.js → Accordion-czmnsspb.js} +5 -5
- package/web-dist/chunks/{Accordion-nc5gnvnb.js → Accordion-dp638q63.js} +2 -2
- package/web-dist/chunks/{Accordion-2fm2tm5r.js → Accordion-e633pb7z.js} +1 -1
- package/web-dist/chunks/{Accordion-yz7b7njb.js → Accordion-f1t3rzgg.js} +4 -4
- package/web-dist/chunks/{Accordion-b3qy1trj.js → Accordion-fm3jxs1f.js} +8 -8
- package/web-dist/chunks/{Accordion-zf3kzvef.js → Accordion-gj63vb6b.js} +4 -4
- package/web-dist/chunks/{Accordion-mvfz28m8.js → Accordion-gkzhd3zk.js} +3 -3
- package/web-dist/chunks/{Accordion-jj3bg8c1.js → Accordion-k7wwyx5x.js} +4 -4
- package/web-dist/chunks/{Accordion-rkv7jyaj.js → Accordion-kemavggr.js} +1 -1
- package/web-dist/chunks/{Accordion-jhwsvx3g.js → Accordion-kpnwdpb5.js} +1 -1
- package/web-dist/chunks/{Accordion-yf6vseep.js → Accordion-q0st659f.js} +82 -89
- package/web-dist/chunks/{Accordion-555gnfmw.js → Accordion-q165k3az.js} +6 -6
- package/web-dist/chunks/{Accordion-9rnepkvk.js → Accordion-q3z741vt.js} +3 -3
- package/web-dist/chunks/{Accordion-z585n0mr.js → Accordion-rjgdrn7y.js} +1 -1
- package/web-dist/chunks/{Accordion-vmz8y01b.js → Accordion-rspy7gjb.js} +6 -6
- package/web-dist/chunks/{Accordion-ycmg06sq.js → Accordion-rx2gzadh.js} +1 -1
- package/web-dist/chunks/{Accordion-45ej9brb.js → Accordion-swys7qts.js} +3 -3
- package/web-dist/chunks/{Accordion-v1dtv6v0.js → Accordion-w0k7gnn9.js} +3 -3
- package/web-dist/chunks/{Accordion-pnvt10cv.js → Accordion-w1afjp87.js} +4 -4
- package/web-dist/chunks/{Accordion-tj61sa5s.js → Accordion-w7jv9y5t.js} +4 -4
- package/web-dist/chunks/{Accordion-s1jhv8gk.js → Accordion-x13vca75.js} +1 -1
- package/web-dist/chunks/{Accordion-73m7z73v.js → Accordion-x1dg1f47.js} +5 -5
- package/web-dist/chunks/{Accordion-1cgz6f8t.js → Accordion-x4rjd7yn.js} +1 -1
- package/web-dist/chunks/{Accordion-nn38n7q4.js → Accordion-xf8cj8z4.js} +3 -3
- package/web-dist/chunks/{Accordion-8hhvtcxp.js → Accordion-xzd0tx46.js} +1 -1
- package/web-dist/components/accordion/Accordion.js +5 -5
- package/web-dist/components/accordion-item/AccordionItem.js +5 -5
- package/web-dist/components/activity-indicator/ActivityIndicator.js +1 -1
- package/web-dist/components/app-bar/AppBar.js +7 -7
- package/web-dist/components/app-shell/AppShell.js +2 -2
- package/web-dist/components/avatar/Avatar.js +5 -5
- package/web-dist/components/avatar-group/AvatarGroup.js +5 -5
- package/web-dist/components/badge/Badge.js +2 -2
- package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +10 -10
- package/web-dist/components/bottom-sheet/BottomSheet.js +3 -3
- package/web-dist/components/bottom-sheet-flat-list/BottomSheetFlatList.js +3 -3
- package/web-dist/components/bottom-sheet-scroll-view/BottomSheetScrollView.js +3 -3
- package/web-dist/components/bottom-sheet-section-list/BottomSheetSectionList.js +3 -3
- package/web-dist/components/bottom-sheet-view/BottomSheetView.js +3 -3
- package/web-dist/components/bottom-sheet-virtualized-list/BottomSheetVirtualizedList.js +3 -3
- package/web-dist/components/breadcrumbs/Breadcrumbs.js +5 -5
- package/web-dist/components/button/Button.js +3 -3
- package/web-dist/components/button-group/ButtonGroup.js +3 -3
- package/web-dist/components/camera-permission-view/CameraPermissionView.js +10 -10
- package/web-dist/components/card/Card.js +9 -9
- package/web-dist/components/card-back/CardBack.js +2 -2
- package/web-dist/components/card-hand/CardHand.js +2 -2
- package/web-dist/components/chat-list-item/ChatListItem.js +7 -7
- package/web-dist/components/checkbox/Checkbox.js +4 -4
- package/web-dist/components/checkbox-group/CheckboxGroup.js +4 -4
- package/web-dist/components/chess-board/ChessBoard.js +2 -2
- package/web-dist/components/chip/Chip.js +5 -5
- package/web-dist/components/chip-group/ChipGroup.js +5 -5
- package/web-dist/components/collection-editor/CollectionEditor.js +9 -9
- package/web-dist/components/content-rail/ContentRail.js +4 -4
- package/web-dist/components/data-table/DataTable.js +14 -14
- package/web-dist/components/date-picker/DatePicker.js +5 -5
- package/web-dist/components/dialog/Dialog.js +4 -4
- package/web-dist/components/divider/Divider.js +2 -2
- package/web-dist/components/empty-state/EmptyState.js +10 -10
- package/web-dist/components/field/Field.js +4 -4
- package/web-dist/components/flat-list/FlatList.js +5 -5
- package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +8 -8
- package/web-dist/components/form/Form.js +6 -6
- package/web-dist/components/form-actions/FormActions.js +6 -6
- package/web-dist/components/form-error/FormError.js +6 -6
- package/web-dist/components/game/Game.js +3 -3
- package/web-dist/components/game-entity/GameEntity.js +3 -3
- package/web-dist/components/game-field/GameField.js +3 -3
- package/web-dist/components/game-input-zone/GameInputZone.js +3 -3
- package/web-dist/components/game-measurement-probe/GameMeasurementProbe.js +3 -3
- package/web-dist/components/game-overlay/GameOverlay.js +3 -3
- package/web-dist/components/gradient/Gradient.js +3 -3
- package/web-dist/components/gradient-renderer-provider/GradientRendererProvider.js +3 -3
- package/web-dist/components/graph-view/GraphView.js +20 -11
- package/web-dist/components/graph-view/GraphView.types-0.d.ts +2 -0
- package/web-dist/components/grid/Grid.js +2 -2
- package/web-dist/components/heading/Heading.js +2 -2
- package/web-dist/components/hero/Hero.js +9 -9
- package/web-dist/components/icon/Icon.js +2 -2
- package/web-dist/components/icon-button/IconButton.js +3 -3
- package/web-dist/components/image/Image.js +4 -4
- package/web-dist/components/keyboard-avoiding-view/KeyboardAvoidingView.js +1 -1
- package/web-dist/components/list/List.js +5 -5
- package/web-dist/components/list-item/ListItem.js +5 -5
- package/web-dist/components/list-section/ListSection.js +5 -5
- package/web-dist/components/media-card/MediaCard.js +9 -9
- package/web-dist/components/message-bubble/MessageBubble.js +7 -7
- package/web-dist/components/metric-card/MetricCard.js +9 -9
- package/web-dist/components/missing-element/MissingElement.js +4 -4
- package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +8 -8
- package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +8 -8
- package/web-dist/components/opening-book/OpeningBook.js +2 -2
- package/web-dist/components/otp-form/OtpForm.js +8 -8
- package/web-dist/components/pagination/Pagination.js +4 -4
- package/web-dist/components/palette-item/PaletteItem.js +9 -9
- package/web-dist/components/playing-card/PlayingCard.js +2 -2
- package/web-dist/components/poker-training-table/PokerTrainingTable.js +2 -2
- package/web-dist/components/popover-menu/PopoverMenu.js +4 -4
- package/web-dist/components/post-card/PostCard.js +9 -9
- package/web-dist/components/product-card/ProductCard.js +9 -9
- package/web-dist/components/progress/Progress.js +4 -4
- package/web-dist/components/progress-ring/ProgressRing.js +4 -4
- package/web-dist/components/radio/Radio.js +5 -5
- package/web-dist/components/radio-group/RadioGroup.js +5 -5
- package/web-dist/components/rating/Rating.js +3 -3
- package/web-dist/components/reader-surface/ReaderSurface.js +9 -9
- package/web-dist/components/scan-overlay/ScanOverlay.js +10 -10
- package/web-dist/components/screen/Screen.js +2 -2
- package/web-dist/components/screen-section/ScreenSection.js +4 -4
- package/web-dist/components/scroll-view/ScrollView.js +2 -2
- package/web-dist/components/search-input/SearchInput.js +4 -4
- package/web-dist/components/section-header/SectionHeader.js +4 -4
- package/web-dist/components/section-list/SectionList.js +5 -5
- package/web-dist/components/select/Select.js +4 -4
- package/web-dist/components/selectable-item/SelectableItem.js +1 -1
- package/web-dist/components/selection-provider/SelectionProvider.js +1 -1
- package/web-dist/components/sign-in-form/SignInForm.js +8 -8
- package/web-dist/components/sign-up-form/SignUpForm.js +8 -8
- package/web-dist/components/skeleton/Skeleton.js +12 -12
- package/web-dist/components/skeleton-card/SkeletonCard.js +12 -12
- package/web-dist/components/skeleton-list/SkeletonList.js +12 -12
- package/web-dist/components/skeleton-text/SkeletonText.js +12 -12
- package/web-dist/components/surface/Surface.js +2 -2
- package/web-dist/components/switch/Switch.js +1 -1
- package/web-dist/components/tab/Tab.js +2 -2
- package/web-dist/components/tab-list/TabList.js +2 -2
- package/web-dist/components/tab-panel/TabPanel.js +2 -2
- package/web-dist/components/tabletop-table/TabletopTable.js +2 -2
- package/web-dist/components/tabs/Tabs.js +2 -2
- package/web-dist/components/text/Text.js +2 -2
- package/web-dist/components/text-input/TextInput.js +4 -4
- package/web-dist/components/time-picker/TimePicker.js +5 -5
- package/web-dist/components/timeline/Timeline.js +4 -4
- package/web-dist/components/toast/Toast.js +2 -2
- package/web-dist/components/toast-provider/ToastProvider.js +2 -2
- package/web-dist/components/toolbar/Toolbar.js +9 -9
- package/web-dist/components/tree-item/TreeItem.js +41 -22
- package/web-dist/components/tree-view/TreeView.d.ts +4 -3
- package/web-dist/components/tree-view/TreeView.js +25 -12
- package/web-dist/components/uploader/Uploader.js +10 -10
- package/web-dist/components/view/View.js +2 -2
- package/web-dist/manifest.json +577 -568
- package/web-dist/runtime/ZoraProvider.js +3 -3
- /package/web-dist/chunks/{Accordion-k3bc4kad.js → Accordion-13y3zx87.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 23.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 2f16225: Unify cross-platform multi-selection intent across Selection, TreeView, and GraphView.
|
|
8
|
+
|
|
9
|
+
## 22.1.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 24915fd: Update dependencies: `@ankhorage/contracts`, `@ankhorage/paradox`, `@ankhorage/utility`.
|
|
14
|
+
|
|
3
15
|
## 22.1.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/zora
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.
|
|
9
9
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { SelectionIntent } from '@ankhorage/utility/selection';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import type { GraphViewElementEventType, GraphViewNode, GraphViewNodeRenderContext, GraphViewRenderedNode, GraphViewSize } from '../../../../../types/graph-view';
|
|
3
4
|
interface GraphNodeOverlayProps {
|
|
4
5
|
readonly nodes: readonly GraphViewNode[];
|
|
5
6
|
readonly renderedNodes: readonly GraphViewRenderedNode[];
|
|
6
7
|
readonly renderNode: (context: GraphViewNodeRenderContext) => React.ReactNode;
|
|
7
|
-
readonly onNodeEvent: (id: string, type: GraphViewElementEventType) => void;
|
|
8
|
+
readonly onNodeEvent: (id: string, type: GraphViewElementEventType, selectionIntent?: SelectionIntent) => void;
|
|
8
9
|
readonly onNodeSize: (id: string, size: GraphViewSize) => void;
|
|
9
10
|
}
|
|
10
11
|
/*** Render optional React node content above Cytoscape at its authoritative rendered positions. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphNodeOverlay.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACb,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACd,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"GraphNodeOverlay.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACb,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACd,MAAM,iCAAiC,CAAC;AAGzC,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACzD,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;IAC9E,QAAQ,CAAC,WAAW,EAAE,CACpB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,yBAAyB,EAC/B,eAAe,CAAC,EAAE,eAAe,KAC9B,IAAI,CAAC;IACV,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAChE;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,qBAgC5D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { resolveSelectionEventIntent } from '../../../../selection/application/resolveSelectionEventIntent';
|
|
2
3
|
/*** Render optional React node content above Cytoscape at its authoritative rendered positions. */
|
|
3
4
|
export function GraphNodeOverlay(props) {
|
|
4
5
|
const nodesById = React.useMemo(() => new Map(props.nodes.map((node) => [node.id, node])), [props.nodes]);
|
|
@@ -41,7 +42,7 @@ function MeasuredGraphNode(props) {
|
|
|
41
42
|
top: renderedNode.position.y,
|
|
42
43
|
transform: `translate(-50%, -50%) scale(${renderedNode.zoom})`,
|
|
43
44
|
transformOrigin: 'center',
|
|
44
|
-
}}
|
|
45
|
+
}} onPointerUp={(event) => props.onNodeEvent(node.id, 'press', resolveSelectionEventIntent(event, 'pointer'))} onDoubleClick={() => props.onNodeEvent(node.id, 'double-press')} onMouseEnter={() => props.onNodeEvent(node.id, 'pointer-enter')} onMouseLeave={() => props.onNodeEvent(node.id, 'pointer-leave')}>
|
|
45
46
|
{props.renderNode({
|
|
46
47
|
hovered: renderedNode.hovered,
|
|
47
48
|
node,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphNodeOverlay.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GraphNodeOverlay.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { SelectionIntent } from '@ankhorage/utility/selection';\nimport React from 'react';\n\nimport type {\n GraphViewElementEventType,\n GraphViewNode,\n GraphViewNodeRenderContext,\n GraphViewRenderedNode,\n GraphViewSize,\n} from '../../../../../types/graph-view';\nimport { resolveSelectionEventIntent } from '../../../../selection/application/resolveSelectionEventIntent';\n\ninterface GraphNodeOverlayProps {\n readonly nodes: readonly GraphViewNode[];\n readonly renderedNodes: readonly GraphViewRenderedNode[];\n readonly renderNode: (context: GraphViewNodeRenderContext) => React.ReactNode;\n readonly onNodeEvent: (\n id: string,\n type: GraphViewElementEventType,\n selectionIntent?: SelectionIntent,\n ) => void;\n readonly onNodeSize: (id: string, size: GraphViewSize) => void;\n}\n\n/*** Render optional React node content above Cytoscape at its authoritative rendered positions. */\nexport function GraphNodeOverlay(props: GraphNodeOverlayProps) {\n const nodesById = React.useMemo(\n () => new Map(props.nodes.map((node) => [node.id, node] as const)),\n [props.nodes],\n );\n\n return (\n <div\n aria-hidden\n style={{\n inset: 0,\n overflow: 'hidden',\n pointerEvents: 'none',\n position: 'absolute',\n }}\n >\n {props.renderedNodes.map((renderedNode) => {\n const node = nodesById.get(renderedNode.id);\n if (!node) return null;\n return (\n <MeasuredGraphNode\n key={node.id}\n node={node}\n renderedNode={renderedNode}\n renderNode={props.renderNode}\n onNodeEvent={props.onNodeEvent}\n onNodeSize={props.onNodeSize}\n />\n );\n })}\n </div>\n );\n}\n\ninterface MeasuredGraphNodeProps {\n readonly node: GraphViewNode;\n readonly renderedNode: GraphViewRenderedNode;\n readonly renderNode: GraphNodeOverlayProps['renderNode'];\n readonly onNodeEvent: GraphNodeOverlayProps['onNodeEvent'];\n readonly onNodeSize: GraphNodeOverlayProps['onNodeSize'];\n}\n\n/*** Measure one rich node at model scale and translate its DOM interactions into graph events. */\nfunction MeasuredGraphNode(props: MeasuredGraphNodeProps) {\n const elementRef = React.useRef<HTMLDivElement | null>(null);\n const { node, onNodeSize, renderedNode } = props;\n\n React.useLayoutEffect(() => {\n const element = elementRef.current;\n if (element === null) return;\n reportElementSize(element, node.id, onNodeSize);\n\n const Observer = readResizeObserverConstructor();\n if (Observer === null) return;\n const observer = new Observer(() => reportElementSize(element, node.id, onNodeSize));\n observer.observe(element);\n return () => observer.disconnect();\n }, [node.id, onNodeSize]);\n\n return (\n <div\n ref={(element) => {\n elementRef.current = element;\n }}\n style={{\n left: renderedNode.position.x,\n pointerEvents: 'auto',\n position: 'absolute',\n top: renderedNode.position.y,\n transform: `translate(-50%, -50%) scale(${renderedNode.zoom})`,\n transformOrigin: 'center',\n }}\n onPointerUp={(event) =>\n props.onNodeEvent(node.id, 'press', resolveSelectionEventIntent(event, 'pointer'))\n }\n onDoubleClick={() => props.onNodeEvent(node.id, 'double-press')}\n onMouseEnter={() => props.onNodeEvent(node.id, 'pointer-enter')}\n onMouseLeave={() => props.onNodeEvent(node.id, 'pointer-leave')}\n >\n {props.renderNode({\n hovered: renderedNode.hovered,\n node,\n selected: renderedNode.selected,\n zoom: renderedNode.zoom,\n })}\n </div>\n );\n}\n\n/*** Report unscaled DOM dimensions only when a measurable node has positive size. */\nfunction reportElementSize(\n element: unknown,\n nodeId: string,\n onNodeSize: (id: string, size: GraphViewSize) => void,\n) {\n const measured = element as {\n readonly offsetHeight?: unknown;\n readonly offsetWidth?: unknown;\n };\n if (typeof measured.offsetWidth !== 'number' || typeof measured.offsetHeight !== 'number') return;\n if (measured.offsetWidth <= 0 || measured.offsetHeight <= 0) return;\n onNodeSize(nodeId, {\n width: measured.offsetWidth,\n height: measured.offsetHeight,\n });\n}\n\n/*** Read ResizeObserver without requiring the DOM lib in the package TypeScript target. */\nfunction readResizeObserverConstructor(): ResizeObserverConstructorLike | null {\n const observer = (\n globalThis as unknown as {\n ResizeObserver?: ResizeObserverConstructorLike;\n }\n ).ResizeObserver;\n return observer ?? null;\n}\n\ninterface ResizeObserverLike {\n disconnect(): void;\n observe(target: unknown): void;\n}\n\ntype ResizeObserverConstructorLike = new (callback: () => void) => ResizeObserverLike;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphView.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,iCAAiC,CAAC;AAMzC;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"GraphView.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,iCAAiC,CAAC;AAMzC;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,qBA+B9C"}
|
|
@@ -25,7 +25,7 @@ export function GraphView(props) {
|
|
|
25
25
|
...props.style,
|
|
26
26
|
}}>
|
|
27
27
|
<div ref={containerRef} style={{ height: '100%', width: '100%' }}/>
|
|
28
|
-
{props.renderNode ? (<GraphNodeOverlay nodes={props.nodes} renderedNodes={renderedNodes} renderNode={props.renderNode} onNodeEvent={(id, type) => runtimeRef.current?.handleOverlayNodeEvent(id, type)} onNodeSize={(id, size) => runtimeRef.current?.setNodeSize(id, size)}/>) : null}
|
|
28
|
+
{props.renderNode ? (<GraphNodeOverlay nodes={props.nodes} renderedNodes={renderedNodes} renderNode={props.renderNode} onNodeEvent={(id, type, selectionIntent) => runtimeRef.current?.handleOverlayNodeEvent(id, type, selectionIntent)} onNodeSize={(id, size) => runtimeRef.current?.setNodeSize(id, size)}/>) : null}
|
|
29
29
|
</div>);
|
|
30
30
|
}
|
|
31
31
|
/*** Compose React synchronization around the single imperative graph runtime. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphView.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { CytoscapeOptions } from 'cytoscape';\nimport React from 'react';\n\nimport type {\n GraphViewCallbacks,\n GraphViewNode,\n GraphViewProps,\n GraphViewRenderedNode,\n} from '../../../../../types/graph-view';\nimport { createGraphRuntime, type GraphRuntime } from './createGraphRuntime';\nimport { GraphNodeOverlay } from './GraphNodeOverlay';\n\ntype GraphContainer = NonNullable<CytoscapeOptions['container']>;\n\n/***\n * Render a browser graph while one runtime owns Cytoscape layout, viewport, and disposal.\n * zoomMode Use `fit-relative` to make controller zoom, events and min/max limits relative\n * to the visible-node fit (1 = fit). The default `absolute` keeps engine-space zoom units.\n * sizeNodesToLabels Opt in to renderer-measured plain labels, including bold and Unicode\n * text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.\n * minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.\n * maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.\n * onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).\n * Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,\n * stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries\n * collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.\n */\nexport function GraphView(props: GraphViewProps) {\n const { containerRef, renderedNodes, runtimeRef } = useGraphViewRuntime(props);\n\n return (\n <div\n aria-label={props.ariaLabel ?? 'Graph'}\n className={props.className}\n role=\"application\"\n style={{\n height: '100%',\n minHeight: 0,\n minWidth: 0,\n position: 'relative',\n width: '100%',\n ...props.style,\n }}\n >\n <div ref={containerRef} style={{ height: '100%', width: '100%' }} />\n {props.renderNode ? (\n <GraphNodeOverlay\n nodes={props.nodes}\n renderedNodes={renderedNodes}\n renderNode={props.renderNode}\n onNodeEvent={(id, type) => runtimeRef.current?.handleOverlayNodeEvent(id, type)}\n onNodeSize={(id, size) => runtimeRef.current?.setNodeSize(id, size)}\n />\n ) : null}\n </div>\n );\n}\n\n/*** Compose React synchronization around the single imperative graph runtime. */\nfunction useGraphViewRuntime(props: GraphViewProps) {\n const containerRef = React.useRef<GraphContainer | null>(null);\n const runtimeRef = React.useRef<GraphRuntime | null>(null);\n const callbacksRef = useGraphCallbacksRef(props);\n const [renderedNodes, setRenderedNodes] = React.useState<readonly GraphViewRenderedNode[]>([]);\n\n useRuntimeLifecycle(containerRef, runtimeRef, callbacksRef);\n useRuntimeGraphUpdate(runtimeRef, props);\n useRuntimeSelection(runtimeRef, props.selectedNodeIds);\n useRenderedNodeSubscription(runtimeRef, props.renderNode, setRenderedNodes);\n useKnownNodeSizes(runtimeRef, props.nodes, props.getNodeSize);\n\n return { containerRef, renderedNodes, runtimeRef };\n}\n\n/*** Keep the callback ref current without mutating refs during render. */\nfunction useGraphCallbacksRef(props: GraphViewProps) {\n const callbacksRef = React.useRef<GraphViewCallbacks>(readCallbacks(props));\n const {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n } = props;\n\n React.useEffect(() => {\n callbacksRef.current = {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n };\n }, [\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n ]);\n\n return callbacksRef;\n}\n\n/*** Create and dispose the runtime only with the underlying browser container lifetime. */\nfunction useRuntimeLifecycle(\n containerRef: { current: GraphContainer | null },\n runtimeRef: { current: GraphRuntime | null },\n callbacksRef: { current: GraphViewCallbacks },\n) {\n React.useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n const runtime = createGraphRuntime(container, callbacksRef);\n runtimeRef.current = runtime;\n return () => {\n runtime.destroy();\n runtimeRef.current = null;\n };\n }, [callbacksRef, containerRef, runtimeRef]);\n}\n\n/*** Synchronize graph data and layout policy without exposing Cytoscape to React. */\nfunction useRuntimeGraphUpdate(\n runtimeRef: { current: GraphRuntime | null },\n props: GraphViewProps,\n) {\n const {\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n spacingFactor,\n styleRules,\n } = props;\n\n React.useEffect(() => {\n runtimeRef.current?.update({\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n richNodeRendering: renderNode !== undefined,\n spacingFactor,\n styleRules,\n });\n }, [\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n runtimeRef,\n spacingFactor,\n styleRules,\n ]);\n}\n\n/*** Synchronize optional controlled selection independently from graph layout. */\nfunction useRuntimeSelection(\n runtimeRef: { current: GraphRuntime | null },\n selectedNodeIds: readonly string[] | undefined,\n) {\n React.useEffect(() => {\n runtimeRef.current?.setSelectedNodeIds(selectedNodeIds);\n }, [runtimeRef, selectedNodeIds]);\n}\n\n/*** Subscribe the optional rich-node overlay to rendered runtime positions. */\nfunction useRenderedNodeSubscription(\n runtimeRef: { current: GraphRuntime | null },\n renderNode: GraphViewProps['renderNode'],\n setRenderedNodes: (nodes: readonly GraphViewRenderedNode[]) => void,\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || renderNode === undefined) {\n setRenderedNodes([]);\n return;\n }\n return runtime.subscribeRenderedNodes(setRenderedNodes);\n }, [renderNode, runtimeRef, setRenderedNodes]);\n}\n\n/*** Seed known rich-node dimensions without requiring DOM measurement. */\nfunction useKnownNodeSizes(\n runtimeRef: { current: GraphRuntime | null },\n nodes: readonly GraphViewNode[],\n getNodeSize: GraphViewProps['getNodeSize'],\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || getNodeSize === undefined) return;\n for (const node of nodes) {\n const size = getNodeSize(node);\n if (size) runtime.setNodeSize(node.id, size);\n }\n }, [getNodeSize, nodes, runtimeRef]);\n}\n\n/*** Read callback props for the initial runtime callback-ref value. */\nfunction readCallbacks(props: GraphViewProps): GraphViewCallbacks {\n return {\n onEdgeEvent: props.onEdgeEvent,\n onLayoutComplete: props.onLayoutComplete,\n onNodeEvent: props.onNodeEvent,\n onReady: props.onReady,\n onViewportChange: props.onViewportChange,\n onSpacingFactorChange: props.onSpacingFactorChange,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GraphView.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,OAAO,EAAE,kBAAkB,EAAqB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAE/E,OAAO,CACL,CAAC,GAAG,CACF,UAAU,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,CACvC,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAC3B,IAAI,CAAC,aAAa,CAClB,KAAK,CAAC,CAAC;YACL,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,MAAM;YACb,GAAG,KAAK,CAAC,KAAK;SACf,CAAC,CAEF;MAAA,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EACjE;MAAA,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAClB,CAAC,gBAAgB,CACf,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CACnB,aAAa,CAAC,CAAC,aAAa,CAAC,CAC7B,UAAU,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAC7B,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,CACzC,UAAU,CAAC,OAAO,EAAE,sBAAsB,CAAC,EAAE,EAAE,IAAI,EAAE,eAAe,CACtE,CAAC,CACD,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,EACpE,CACH,CAAC,CAAC,CAAC,IAAI,CACV;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,SAAS,mBAAmB,CAAC,KAAqB;IAChD,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAwB,IAAI,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAsB,IAAI,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAmC,EAAE,CAAC,CAAC;IAE/F,mBAAmB,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAC5D,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACzC,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACvD,2BAA2B,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IAC5E,iBAAiB,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAE9D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AACrD,CAAC;AAED,0EAA0E;AAC1E,SAAS,oBAAoB,CAAC,KAAqB;IACjD,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAqB,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5E,MAAM,EACJ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,qBAAqB,GACtB,GAAG,KAAK,CAAC;IAEV,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,YAAY,CAAC,OAAO,GAAG;YACrB,WAAW;YACX,gBAAgB;YAChB,WAAW;YACX,OAAO;YACP,gBAAgB;YAChB,qBAAqB;SACtB,CAAC;IACJ,CAAC,EAAE;QACD,WAAW;QACX,gBAAgB;QAChB,WAAW;QACX,OAAO;QACP,gBAAgB;QAChB,qBAAqB;KACtB,CAAC,CAAC;IAEH,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,2FAA2F;AAC3F,SAAS,mBAAmB,CAC1B,YAAgD,EAChD,UAA4C,EAC5C,YAA6C;IAE7C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACvC,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO;QAC/B,MAAM,OAAO,GAAG,kBAAkB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC5D,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,OAAO,EAAE,CAAC;YAClB,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,qFAAqF;AACrF,SAAS,qBAAqB,CAC5B,UAA4C,EAC5C,KAAqB;IAErB,MAAM,EACJ,KAAK,EACL,UAAU,EACV,MAAM,EACN,aAAa,EACb,OAAO,EACP,oBAAoB,EACpB,eAAe,EACf,OAAO,EACP,QAAQ,EACR,iBAAiB,EACjB,KAAK,EACL,UAAU,EACV,aAAa,EACb,UAAU,GACX,GAAG,KAAK,CAAC;IAEV,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;YACzB,KAAK;YACL,UAAU;YACV,MAAM;YACN,aAAa;YACb,OAAO;YACP,oBAAoB;YACpB,eAAe;YACf,OAAO;YACP,QAAQ;YACR,iBAAiB;YACjB,KAAK;YACL,iBAAiB,EAAE,UAAU,KAAK,SAAS;YAC3C,aAAa;YACb,UAAU;SACX,CAAC,CAAC;IACL,CAAC,EAAE;QACD,KAAK;QACL,UAAU;QACV,MAAM;QACN,aAAa;QACb,OAAO;QACP,oBAAoB;QACpB,eAAe;QACf,OAAO;QACP,QAAQ;QACR,iBAAiB;QACjB,KAAK;QACL,UAAU;QACV,UAAU;QACV,aAAa;QACb,UAAU;KACX,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAClF,SAAS,mBAAmB,CAC1B,UAA4C,EAC5C,eAA8C;IAE9C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,UAAU,CAAC,OAAO,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,+EAA+E;AAC/E,SAAS,2BAA2B,CAClC,UAA4C,EAC5C,UAAwC,EACxC,gBAAmE;IAEnE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;QACnC,IAAI,OAAO,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YACjD,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,OAAO,OAAO,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,0EAA0E;AAC1E,SAAS,iBAAiB,CACxB,UAA4C,EAC5C,KAA+B,EAC/B,WAA0C;IAE1C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;QACnC,IAAI,OAAO,KAAK,IAAI,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO;QAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,IAAI;gBAAE,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,uEAAuE;AACvE,SAAS,aAAa,CAAC,KAAqB;IAC1C,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;KACnD,CAAC;AACJ,CAAC","sourcesContent":["import type { CytoscapeOptions } from 'cytoscape';\nimport React from 'react';\n\nimport type {\n GraphViewCallbacks,\n GraphViewNode,\n GraphViewProps,\n GraphViewRenderedNode,\n} from '../../../../../types/graph-view';\nimport { createGraphRuntime, type GraphRuntime } from './createGraphRuntime';\nimport { GraphNodeOverlay } from './GraphNodeOverlay';\n\ntype GraphContainer = NonNullable<CytoscapeOptions['container']>;\n\n/***\n * Render a browser graph while one runtime owns Cytoscape layout, viewport, and disposal.\n * zoomMode Use `fit-relative` to make controller zoom, events and min/max limits relative\n * to the visible-node fit (1 = fit). The default `absolute` keeps engine-space zoom units.\n * sizeNodesToLabels Opt in to renderer-measured plain labels, including bold and Unicode\n * text. Keep padding in styleRules. Compound and rich-node dimensions retain their existing owners.\n * minReadableLabelSize Expand the manual zoom ceiling until plain labels reach this CSS-pixel size.\n * maxFitLabelSize Cap automatic fitting at this plain-label CSS-pixel size, leaving whitespace for tiny graphs.\n * onSpacingFactorChange Receive the spacing accepted by explicit fit({ optimizeSpacing: true }).\n * Ordinary zoom never adjusts spacing or relayouts. Explicit optimization preserves layout ordering,\n * stops once effective fit reaches maxFitLabelSize, keeps labels and unrelated compound boundaries\n * collision-safe, and permits only a small rendered background-overlap fallback for dense graphs.\n */\nexport function GraphView(props: GraphViewProps) {\n const { containerRef, renderedNodes, runtimeRef } = useGraphViewRuntime(props);\n\n return (\n <div\n aria-label={props.ariaLabel ?? 'Graph'}\n className={props.className}\n role=\"application\"\n style={{\n height: '100%',\n minHeight: 0,\n minWidth: 0,\n position: 'relative',\n width: '100%',\n ...props.style,\n }}\n >\n <div ref={containerRef} style={{ height: '100%', width: '100%' }} />\n {props.renderNode ? (\n <GraphNodeOverlay\n nodes={props.nodes}\n renderedNodes={renderedNodes}\n renderNode={props.renderNode}\n onNodeEvent={(id, type, selectionIntent) =>\n runtimeRef.current?.handleOverlayNodeEvent(id, type, selectionIntent)\n }\n onNodeSize={(id, size) => runtimeRef.current?.setNodeSize(id, size)}\n />\n ) : null}\n </div>\n );\n}\n\n/*** Compose React synchronization around the single imperative graph runtime. */\nfunction useGraphViewRuntime(props: GraphViewProps) {\n const containerRef = React.useRef<GraphContainer | null>(null);\n const runtimeRef = React.useRef<GraphRuntime | null>(null);\n const callbacksRef = useGraphCallbacksRef(props);\n const [renderedNodes, setRenderedNodes] = React.useState<readonly GraphViewRenderedNode[]>([]);\n\n useRuntimeLifecycle(containerRef, runtimeRef, callbacksRef);\n useRuntimeGraphUpdate(runtimeRef, props);\n useRuntimeSelection(runtimeRef, props.selectedNodeIds);\n useRenderedNodeSubscription(runtimeRef, props.renderNode, setRenderedNodes);\n useKnownNodeSizes(runtimeRef, props.nodes, props.getNodeSize);\n\n return { containerRef, renderedNodes, runtimeRef };\n}\n\n/*** Keep the callback ref current without mutating refs during render. */\nfunction useGraphCallbacksRef(props: GraphViewProps) {\n const callbacksRef = React.useRef<GraphViewCallbacks>(readCallbacks(props));\n const {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n } = props;\n\n React.useEffect(() => {\n callbacksRef.current = {\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n };\n }, [\n onEdgeEvent,\n onLayoutComplete,\n onNodeEvent,\n onReady,\n onViewportChange,\n onSpacingFactorChange,\n ]);\n\n return callbacksRef;\n}\n\n/*** Create and dispose the runtime only with the underlying browser container lifetime. */\nfunction useRuntimeLifecycle(\n containerRef: { current: GraphContainer | null },\n runtimeRef: { current: GraphRuntime | null },\n callbacksRef: { current: GraphViewCallbacks },\n) {\n React.useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n const runtime = createGraphRuntime(container, callbacksRef);\n runtimeRef.current = runtime;\n return () => {\n runtime.destroy();\n runtimeRef.current = null;\n };\n }, [callbacksRef, containerRef, runtimeRef]);\n}\n\n/*** Synchronize graph data and layout policy without exposing Cytoscape to React. */\nfunction useRuntimeGraphUpdate(\n runtimeRef: { current: GraphRuntime | null },\n props: GraphViewProps,\n) {\n const {\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n spacingFactor,\n styleRules,\n } = props;\n\n React.useEffect(() => {\n runtimeRef.current?.update({\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n richNodeRendering: renderNode !== undefined,\n spacingFactor,\n styleRules,\n });\n }, [\n edges,\n fitPadding,\n layout,\n layoutOptions,\n maxZoom,\n minReadableLabelSize,\n maxFitLabelSize,\n minZoom,\n zoomMode,\n sizeNodesToLabels,\n nodes,\n renderNode,\n runtimeRef,\n spacingFactor,\n styleRules,\n ]);\n}\n\n/*** Synchronize optional controlled selection independently from graph layout. */\nfunction useRuntimeSelection(\n runtimeRef: { current: GraphRuntime | null },\n selectedNodeIds: readonly string[] | undefined,\n) {\n React.useEffect(() => {\n runtimeRef.current?.setSelectedNodeIds(selectedNodeIds);\n }, [runtimeRef, selectedNodeIds]);\n}\n\n/*** Subscribe the optional rich-node overlay to rendered runtime positions. */\nfunction useRenderedNodeSubscription(\n runtimeRef: { current: GraphRuntime | null },\n renderNode: GraphViewProps['renderNode'],\n setRenderedNodes: (nodes: readonly GraphViewRenderedNode[]) => void,\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || renderNode === undefined) {\n setRenderedNodes([]);\n return;\n }\n return runtime.subscribeRenderedNodes(setRenderedNodes);\n }, [renderNode, runtimeRef, setRenderedNodes]);\n}\n\n/*** Seed known rich-node dimensions without requiring DOM measurement. */\nfunction useKnownNodeSizes(\n runtimeRef: { current: GraphRuntime | null },\n nodes: readonly GraphViewNode[],\n getNodeSize: GraphViewProps['getNodeSize'],\n) {\n React.useEffect(() => {\n const runtime = runtimeRef.current;\n if (runtime === null || getNodeSize === undefined) return;\n for (const node of nodes) {\n const size = getNodeSize(node);\n if (size) runtime.setNodeSize(node.id, size);\n }\n }, [getNodeSize, nodes, runtimeRef]);\n}\n\n/*** Read callback props for the initial runtime callback-ref value. */\nfunction readCallbacks(props: GraphViewProps): GraphViewCallbacks {\n return {\n onEdgeEvent: props.onEdgeEvent,\n onLayoutComplete: props.onLayoutComplete,\n onNodeEvent: props.onNodeEvent,\n onReady: props.onReady,\n onViewportChange: props.onViewportChange,\n onSpacingFactorChange: props.onSpacingFactorChange,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindGraphEvents.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"bindGraphEvents.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EAGpB,MAAM,iCAAiC,CAAC;AAGzC,iFAAiF;AACjF,wBAAgB,eAAe,CAC7B,EAAE,EAAE,IAAI,EACR,YAAY,EAAE;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,EAC7C,UAAU,EAAE,mBAAmB,EAC/B,eAAe,EAAE,MAAM,IAAI,cAe5B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveSelectionEventIntent } from '../../../../selection/application/resolveSelectionEventIntent';
|
|
1
2
|
/*** Bind stable Cytoscape events that always read the latest React callbacks. */
|
|
2
3
|
export function bindGraphEvents(cy, callbacksRef, controller, onRuntimeChange) {
|
|
3
4
|
const nodeHandlers = bindElementEvents(cy, 'node', callbacksRef, onRuntimeChange);
|
|
@@ -20,16 +21,23 @@ function bindElementEvents(cy, selector, callbacksRef, onRuntimeChange) {
|
|
|
20
21
|
const target = event.target;
|
|
21
22
|
if (!isGraphEventTarget(target))
|
|
22
23
|
return;
|
|
23
|
-
emitElementEvent(callbacksRef.current, selector,
|
|
24
|
-
id: target.id(),
|
|
25
|
-
type,
|
|
26
|
-
});
|
|
24
|
+
emitElementEvent(callbacksRef.current, selector, createElementEvent(event, target.id(), type));
|
|
27
25
|
onRuntimeChange();
|
|
28
26
|
};
|
|
29
27
|
cy.on(cytoscapeEvent, selector, handler);
|
|
30
28
|
return { cytoscapeEvent, handler };
|
|
31
29
|
});
|
|
32
30
|
}
|
|
31
|
+
/*** Translate one renderer event into the engine-neutral public event contract. */
|
|
32
|
+
function createElementEvent(event, id, type) {
|
|
33
|
+
if (type !== 'press')
|
|
34
|
+
return { id, type };
|
|
35
|
+
return {
|
|
36
|
+
id,
|
|
37
|
+
type,
|
|
38
|
+
selectionIntent: resolveSelectionEventIntent(event, 'pointer'),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
33
41
|
/*** Return whether a Cytoscape event target exposes the element identifier contract. */
|
|
34
42
|
function isGraphEventTarget(value) {
|
|
35
43
|
return (typeof value === 'object' && value !== null && 'id' in value && typeof value.id === 'function');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindGraphEvents.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.ts"],"names":[],"mappings":"AAQA,iFAAiF;AACjF,MAAM,UAAU,eAAe,CAC7B,EAAQ,EACR,YAA6C,EAC7C,UAA+B,EAC/B,eAA2B;IAE3B,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;IAClF,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;IAClF,MAAM,eAAe,GAAG,GAAG,EAAE;QAC3B,YAAY,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;QAClE,eAAe,EAAE,CAAC;IACpB,CAAC,CAAC;IACF,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAEnC,OAAO,GAAG,EAAE;QACV,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QAC9C,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QAC9C,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACtC,CAAC,CAAC;AACJ,CAAC;AASD,2FAA2F;AAC3F,SAAS,iBAAiB,CACxB,EAAQ,EACR,QAAyB,EACzB,YAA6C,EAC7C,eAA2B;IAE3B,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;QAChD,MAAM,OAAO,GAAG,CAAC,KAAkB,EAAE,EAAE;YACrC,MAAM,MAAM,GAAY,KAAK,CAAC,MAAM,CAAC;YACrC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;gBAAE,OAAO;YACxC,gBAAgB,
|
|
1
|
+
{"version":3,"file":"bindGraphEvents.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Core, EventObject } from 'cytoscape';\n\nimport type {\n GraphViewCallbacks,\n GraphViewController,\n GraphViewElementEvent,\n GraphViewElementEventType,\n} from '../../../../../types/graph-view';\nimport { resolveSelectionEventIntent } from '../../../../selection/application/resolveSelectionEventIntent';\n\n/*** Bind stable Cytoscape events that always read the latest React callbacks. */\nexport function bindGraphEvents(\n cy: Core,\n callbacksRef: { current: GraphViewCallbacks },\n controller: GraphViewController,\n onRuntimeChange: () => void,\n) {\n const nodeHandlers = bindElementEvents(cy, 'node', callbacksRef, onRuntimeChange);\n const edgeHandlers = bindElementEvents(cy, 'edge', callbacksRef, onRuntimeChange);\n const viewportHandler = () => {\n callbacksRef.current.onViewportChange?.(controller.getViewport());\n onRuntimeChange();\n };\n cy.on('zoom pan', viewportHandler);\n\n return () => {\n unbindElementEvents(cy, 'node', nodeHandlers);\n unbindElementEvents(cy, 'edge', edgeHandlers);\n cy.off('zoom pan', viewportHandler);\n };\n}\n\ntype ElementSelector = 'edge' | 'node';\n\ninterface BoundElementHandler {\n readonly cytoscapeEvent: string;\n readonly handler: (event: EventObject) => void;\n}\n\n/*** Bind one selector's translated event set without resubscribing on callback changes. */\nfunction bindElementEvents(\n cy: Core,\n selector: ElementSelector,\n callbacksRef: { current: GraphViewCallbacks },\n onRuntimeChange: () => void,\n): readonly BoundElementHandler[] {\n return EVENT_TYPES.map(([cytoscapeEvent, type]) => {\n const handler = (event: EventObject) => {\n const target: unknown = event.target;\n if (!isGraphEventTarget(target)) return;\n emitElementEvent(\n callbacksRef.current,\n selector,\n createElementEvent(event, target.id(), type),\n );\n onRuntimeChange();\n };\n cy.on(cytoscapeEvent, selector, handler);\n return { cytoscapeEvent, handler };\n });\n}\n\n/*** Translate one renderer event into the engine-neutral public event contract. */\nfunction createElementEvent(\n event: EventObject,\n id: string,\n type: GraphViewElementEventType,\n): GraphViewElementEvent {\n if (type !== 'press') return { id, type };\n return {\n id,\n type,\n selectionIntent: resolveSelectionEventIntent(event, 'pointer'),\n };\n}\n\n/*** Return whether a Cytoscape event target exposes the element identifier contract. */\nfunction isGraphEventTarget(value: unknown): value is GraphEventTarget {\n return (\n typeof value === 'object' && value !== null && 'id' in value && typeof value.id === 'function'\n );\n}\n\ninterface GraphEventTarget {\n id(): string;\n}\n\n/*** Emit one translated element event without dynamic callback-property access. */\nfunction emitElementEvent(\n callbacks: GraphViewCallbacks,\n selector: ElementSelector,\n event: GraphViewElementEvent,\n) {\n if (selector === 'node') {\n callbacks.onNodeEvent?.(event);\n return;\n }\n callbacks.onEdgeEvent?.(event);\n}\n\n/*** Remove one selector's event handlers using the exact bound callback identities. */\nfunction unbindElementEvents(\n cy: Core,\n selector: ElementSelector,\n handlers: readonly BoundElementHandler[],\n) {\n for (const { cytoscapeEvent, handler } of handlers) {\n cy.off(cytoscapeEvent, selector, handler);\n }\n}\n\nconst EVENT_TYPES = [\n ['tap', 'press'],\n ['dbltap', 'double-press'],\n ['select', 'select'],\n ['unselect', 'unselect'],\n ['mouseover', 'pointer-enter'],\n ['mouseout', 'pointer-leave'],\n] as const satisfies readonly (readonly [string, GraphViewElementEventType])[];\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SelectionIntent } from '@ankhorage/utility/selection';
|
|
1
2
|
import { type CytoscapeOptions } from 'cytoscape';
|
|
2
3
|
import type { GraphViewCallbacks, GraphViewElementEventType, GraphViewRenderedNode, GraphViewSize } from '../../../../../types/graph-view';
|
|
3
4
|
import type { GraphRuntimeUpdate } from '../../../../../types/graphViewRuntime';
|
|
@@ -5,7 +6,7 @@ type GraphContainer = CytoscapeOptions['container'];
|
|
|
5
6
|
type RenderedNodeListener = (nodes: readonly GraphViewRenderedNode[]) => void;
|
|
6
7
|
export interface GraphRuntime {
|
|
7
8
|
destroy(): void;
|
|
8
|
-
handleOverlayNodeEvent(id: string, type: GraphViewElementEventType): void;
|
|
9
|
+
handleOverlayNodeEvent(id: string, type: GraphViewElementEventType, selectionIntent?: SelectionIntent): void;
|
|
9
10
|
setNodeSize(id: string, size: GraphViewSize): void;
|
|
10
11
|
setSelectedNodeIds(nodeIds: readonly string[] | undefined): void;
|
|
11
12
|
subscribeRenderedNodes(listener: RenderedNodeListener): () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createGraphRuntime.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAa,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAExE,OAAO,KAAK,EACV,kBAAkB,EAClB,yBAAyB,EAEzB,qBAAqB,EACrB,aAAa,EAEd,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAiBhF,KAAK,cAAc,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;AACpD,KAAK,oBAAoB,GAAG,CAAC,KAAK,EAAE,SAAS,qBAAqB,EAAE,KAAK,IAAI,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"createGraphRuntime.d.ts","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAkB,EAAa,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAExE,OAAO,KAAK,EACV,kBAAkB,EAClB,yBAAyB,EAEzB,qBAAqB,EACrB,aAAa,EAEd,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAiBhF,KAAK,cAAc,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;AACpD,KAAK,oBAAoB,GAAG,CAAC,KAAK,EAAE,SAAS,qBAAqB,EAAE,KAAK,IAAI,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,sBAAsB,CACpB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,yBAAyB,EAC/B,eAAe,CAAC,EAAE,eAAe,GAChC,IAAI,CAAC;IACR,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IACnD,kBAAkB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC;IACjE,sBAAsB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;IACnE,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACzC;AA4BD,6FAA6F;AAC7F,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,cAAc,EACzB,YAAY,EAAE;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,GAC5C,YAAY,CAoBd"}
|
|
@@ -27,7 +27,7 @@ export function createGraphRuntime(container, callbacksRef) {
|
|
|
27
27
|
const state = createRuntimeState(cy, container, callbacksRef);
|
|
28
28
|
return {
|
|
29
29
|
destroy: () => destroyRuntime(state),
|
|
30
|
-
handleOverlayNodeEvent: (id, type) => handleOverlayNodeEvent(state, id, type),
|
|
30
|
+
handleOverlayNodeEvent: (id, type, selectionIntent) => handleOverlayNodeEvent(state, id, type, selectionIntent),
|
|
31
31
|
setNodeSize: (id, size) => setNodeSize(state, id, size),
|
|
32
32
|
setSelectedNodeIds: (nodeIds) => setSelectedNodeIds(state, nodeIds),
|
|
33
33
|
subscribeRenderedNodes: (listener) => subscribeRenderedNodes(state, listener),
|
|
@@ -317,14 +317,14 @@ function emitRenderedNodes(state) {
|
|
|
317
317
|
listener(nodes);
|
|
318
318
|
}
|
|
319
319
|
/*** Translate one rich-overlay event back into normal graph selection and callbacks. */
|
|
320
|
-
function handleOverlayNodeEvent(state, id, type) {
|
|
320
|
+
function handleOverlayNodeEvent(state, id, type, selectionIntent) {
|
|
321
321
|
if (type === 'pointer-enter')
|
|
322
322
|
state.hoveredNodeIds.add(id);
|
|
323
323
|
if (type === 'pointer-leave')
|
|
324
324
|
state.hoveredNodeIds.delete(id);
|
|
325
325
|
if (type === 'press')
|
|
326
326
|
state.cy.getElementById(id).select();
|
|
327
|
-
state.callbacksRef.current.onNodeEvent?.({ id, type });
|
|
327
|
+
state.callbacksRef.current.onNodeEvent?.({ id, type, selectionIntent });
|
|
328
328
|
emitRenderedNodes(state);
|
|
329
329
|
}
|
|
330
330
|
/*** Return whether Cytoscape currently has dimensions suitable for fitting. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createGraphRuntime.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["import cytoscape, { type Core, type CytoscapeOptions } from 'cytoscape';\n\nimport type {\n GraphViewCallbacks,\n GraphViewElementEventType,\n GraphViewFitOptions,\n GraphViewRenderedNode,\n GraphViewSize,\n GraphViewStyleRule,\n} from '../../../../../types/graph-view';\nimport type { GraphRuntimeUpdate } from '../../../../../types/graphViewRuntime';\nimport { bindGraphEvents } from './bindGraphEvents';\nimport { compactGraphSpacing } from './compactGraphSpacing';\nimport { createGraphController } from './createGraphController';\nimport { createGraphLoopSizer } from './createGraphLoopSizer';\nimport { createGraphResizeObserver, type GraphResizeObserver } from './createGraphResizeObserver';\nimport { getGraphGeometryKey } from './getGraphGeometryKey';\nimport { getGraphTopologyKey } from './getGraphTopologyKey';\nimport { hasGraphLayoutChanged } from './hasGraphLayoutChanged';\nimport { readGraphRenderedNodes } from './readGraphRenderedNodes';\nimport { registerGraphLayouts } from './registerGraphLayouts';\nimport { runGraphLayout } from './runGraphLayout';\nimport { scheduleGraphFrame } from './scheduleGraphFrame';\nimport { shouldFitGraphAfterLayout } from './shouldFitGraphAfterLayout';\nimport { sizeGraphNodesToLabels } from './sizeGraphNodesToLabels';\nimport { syncGraphElements } from './syncGraphElements';\n\ntype GraphContainer = CytoscapeOptions['container'];\ntype RenderedNodeListener = (nodes: readonly GraphViewRenderedNode[]) => void;\n\nexport interface GraphRuntime {\n destroy(): void;\n handleOverlayNodeEvent(id: string, type: GraphViewElementEventType): void;\n setNodeSize(id: string, size: GraphViewSize): void;\n setSelectedNodeIds(nodeIds: readonly string[] | undefined): void;\n subscribeRenderedNodes(listener: RenderedNodeListener): () => void;\n update(input: GraphRuntimeUpdate): void;\n}\n\ninterface GraphRuntimeState {\n readonly fitRequestRef: { current: GraphViewFitOptions | null };\n readonly optimizedSpacingRef: { current: number | null };\n readonly callbacksRef: { current: GraphViewCallbacks };\n readonly controller: ReturnType<typeof createGraphController>['controller'];\n readonly viewport: ReturnType<typeof createGraphController>;\n readonly cy: Core;\n readonly fitPaddingRef: { current: number };\n readonly generationRef: { current: number };\n readonly geometryRef: { current: string | null };\n readonly hoveredNodeIds: Set<string>;\n readonly latestUpdateRef: { current: GraphRuntimeUpdate | null };\n readonly layoutRef: { current: ReturnType<typeof runGraphLayout> | null };\n readonly layoutRunningRef: { current: boolean };\n readonly nodeSizes: Map<string, GraphViewSize>;\n readonly labelSizedNodeIds: Set<string>;\n readonly loopSizer: ReturnType<typeof createGraphLoopSizer>;\n readonly pendingInitialFitRef: { current: boolean };\n readonly readyRef: { current: boolean };\n readonly settledTopologyRef: { current: string | null };\n readonly relayoutScheduledRef: { current: boolean };\n readonly renderedNodeListeners: Set<RenderedNodeListener>;\n readonly resizeObserver: GraphResizeObserver | null;\n readonly unbindEvents: () => void;\n}\n\n/*** Create one Cytoscape runtime that exclusively owns layout, fit, resize, and disposal. */\nexport function createGraphRuntime(\n container: GraphContainer,\n callbacksRef: { current: GraphViewCallbacks },\n): GraphRuntime {\n const cy = cytoscape({\n container,\n elements: [],\n minZoom: 0.05,\n maxZoom: 2,\n selectionType: 'additive',\n userPanningEnabled: true,\n });\n const state = createRuntimeState(cy, container, callbacksRef);\n\n return {\n destroy: () => destroyRuntime(state),\n handleOverlayNodeEvent: (id, type) => handleOverlayNodeEvent(state, id, type),\n setNodeSize: (id, size) => setNodeSize(state, id, size),\n setSelectedNodeIds: (nodeIds) => setSelectedNodeIds(state, nodeIds),\n subscribeRenderedNodes: (listener) => subscribeRenderedNodes(state, listener),\n update: (input) => updateRuntime(state, input),\n };\n}\n\n/*** Build the mutable state shared by the single graph-runtime owner. */\nfunction createRuntimeState(\n cy: Core,\n container: GraphContainer,\n callbacksRef: { current: GraphViewCallbacks },\n): GraphRuntimeState {\n const fitPaddingRef = { current: 50 };\n const viewport = createGraphController(cy, fitPaddingRef, (options) =>\n requestOptimizedFit(state, options),\n );\n const { controller } = viewport;\n const layoutRunningRef = { current: false };\n const readyRef = { current: false };\n const renderedNodeListeners = new Set<RenderedNodeListener>();\n const stateBase = {\n fitRequestRef: { current: null as GraphViewFitOptions | null },\n optimizedSpacingRef: { current: null as number | null },\n callbacksRef,\n controller,\n viewport,\n cy,\n fitPaddingRef,\n generationRef: { current: 0 },\n geometryRef: { current: null as string | null },\n hoveredNodeIds: new Set<string>(),\n latestUpdateRef: { current: null as GraphRuntimeUpdate | null },\n layoutRef: { current: null as ReturnType<typeof runGraphLayout> | null },\n layoutRunningRef,\n nodeSizes: new Map<string, GraphViewSize>(),\n labelSizedNodeIds: new Set<string>(),\n loopSizer: createGraphLoopSizer(cy),\n pendingInitialFitRef: { current: false },\n readyRef,\n settledTopologyRef: { current: null as string | null },\n relayoutScheduledRef: { current: false },\n renderedNodeListeners,\n };\n const unbindEvents = bindGraphEvents(cy, callbacksRef, controller, () =>\n emitRenderedNodes(stateBase),\n );\n const resizeObserver = createGraphResizeObserver({\n container,\n cy,\n settleViewport: () => viewport.settle(true),\n layoutRunningRef,\n pendingInitialFitRef: stateBase.pendingInitialFitRef,\n onViewportSettled: (completedPendingInitialFit) => {\n emitRenderedNodes(stateBase);\n if (!completedPendingInitialFit || readyRef.current) return;\n readyRef.current = true;\n callbacksRef.current.onReady?.(controller);\n callbacksRef.current.onLayoutComplete?.(controller);\n },\n readyRef,\n });\n\n const state = { ...stateBase, resizeObserver, unbindEvents };\n return state;\n}\n\n/***\n * Reconcile presentation in place and relayout only when graph geometry or layout policy changes.\n * Batch reconciliation and skip layout for presentation-only updates.\n */\nfunction updateRuntime(state: GraphRuntimeState, input: GraphRuntimeUpdate) {\n if (state.cy.destroyed()) return;\n const last = state.latestUpdateRef.current;\n const acceptsSpacing =\n state.optimizedSpacingRef.current !== null &&\n state.optimizedSpacingRef.current === input.spacingFactor;\n const previous = acceptsSpacing && last ? { ...last, spacingFactor: input.spacingFactor } : last;\n if (acceptsSpacing) state.optimizedSpacingRef.current = null;\n state.latestUpdateRef.current = input;\n state.fitPaddingRef.current = input.fitPadding ?? 50;\n state.viewport.configure(input);\n state.cy.batch(() => {\n if (previous?.nodes !== input.nodes || previous.edges !== input.edges) {\n syncGraphElements(state.cy, input.nodes, input.edges);\n }\n if (\n previous?.styleRules !== input.styleRules ||\n previous?.richNodeRendering !== input.richNodeRendering\n ) {\n state.loopSizer.reset();\n applyGraphStyles(state.cy, input.styleRules, input.richNodeRendering);\n }\n });\n sizeGraphNodesToLabels(\n state.cy,\n state.labelSizedNodeIds,\n input.sizeNodesToLabels === true && !input.richNodeRendering,\n );\n applyKnownNodeSizes(state);\n state.loopSizer.update();\n const geometry = getGraphGeometryKey(state.cy);\n const relayout = geometry !== state.geometryRef.current || hasGraphLayoutChanged(previous, input);\n state.geometryRef.current = geometry;\n if (!relayout) {\n if (\n previous?.zoomMode !== input.zoomMode ||\n previous?.fitPadding !== input.fitPadding ||\n previous?.minZoom !== input.minZoom ||\n previous?.maxZoom !== input.maxZoom ||\n previous?.minReadableLabelSize !== input.minReadableLabelSize ||\n previous?.maxFitLabelSize !== input.maxFitLabelSize\n ) {\n state.viewport.settle(previous?.zoomMode !== input.zoomMode);\n }\n emitRenderedNodes(state);\n if (!state.layoutRunningRef.current && !state.pendingInitialFitRef.current)\n state.callbacksRef.current.onLayoutComplete?.(state.controller);\n return;\n }\n stopCurrentLayout(state);\n state.fitRequestRef.current = null;\n state.optimizedSpacingRef.current = null;\n startCurrentLayout(state, input);\n}\n\n/*** Start a generation-safe layout whose completion is the only normal automatic fit trigger. */\nfunction startCurrentLayout(state: GraphRuntimeState, input: GraphRuntimeUpdate) {\n state.pendingInitialFitRef.current = false;\n const generation = state.generationRef.current + 1;\n state.generationRef.current = generation;\n state.layoutRunningRef.current = true;\n state.cy.resize();\n state.layoutRef.current = runGraphLayout(\n state.cy,\n {\n layout: input.layout ?? 'concentric',\n layoutOptions: input.layoutOptions,\n spacingFactor: input.spacingFactor ?? 1,\n },\n () => completeCurrentLayout(state, generation),\n );\n}\n\n/***\n * Settle only the latest layout generation and fit once from node bounds.\n * Discard stale completions and avoid repeated automatic fits.\n */\nfunction completeCurrentLayout(state: GraphRuntimeState, generation: number) {\n scheduleGraphFrame(() => {\n if (state.cy.destroyed() || generation !== state.generationRef.current) return;\n state.loopSizer.update();\n state.layoutRef.current = null;\n state.cy.resize();\n state.layoutRunningRef.current = false;\n if (!hasUsableViewport(state.cy)) {\n if (!state.readyRef.current) state.pendingInitialFitRef.current = true;\n return;\n }\n state.pendingInitialFitRef.current = false;\n const input = state.latestUpdateRef.current;\n if (input === null) return;\n const topology = getGraphTopologyKey(input.nodes, input.edges);\n const shouldFit = shouldFitGraphAfterLayout(\n state.readyRef.current,\n topology !== state.settledTopologyRef.current,\n );\n state.viewport.settle(shouldFit);\n state.settledTopologyRef.current = topology;\n const fitRequest = state.fitRequestRef.current;\n state.fitRequestRef.current = null;\n if (fitRequest) requestOptimizedFit(state, fitRequest);\n emitRenderedNodes(state);\n\n if (!state.readyRef.current) {\n state.readyRef.current = true;\n state.callbacksRef.current.onReady?.(state.controller);\n }\n state.callbacksRef.current.onLayoutComplete?.(state.controller);\n });\n}\n\n/***\n * Handle explicit readable-fit intent in the runtime owner, never from zoom or React effects.\n * Bounded spacing optimization preserves the settled algorithm instead of repeatedly running it.\n */\nfunction requestOptimizedFit(state: GraphRuntimeState, options: GraphViewFitOptions) {\n if (state.cy.destroyed()) return;\n if (state.layoutRunningRef.current) {\n state.fitRequestRef.current = options;\n return;\n }\n const input = state.latestUpdateRef.current;\n if (!input) return;\n const previous = state.optimizedSpacingRef.current ?? input.spacingFactor ?? 1;\n const spacing = compactGraphSpacing(state.cy, previous, {\n fitPadding: options.padding ?? state.fitPaddingRef.current,\n maxFitZoom: state.viewport.getFitZoomLimit(),\n minReadableZoom: state.viewport.getReadableZoomTarget(),\n });\n state.geometryRef.current = getGraphGeometryKey(state.cy);\n state.loopSizer.update();\n state.viewport.settle(false);\n state.controller.fit({ ...options, optimizeSpacing: false });\n if (spacing !== previous) {\n state.optimizedSpacingRef.current = spacing;\n state.callbacksRef.current.onSpacingFactorChange?.(spacing);\n }\n emitRenderedNodes(state);\n}\n\n/*** Stop the current layout and invalidate every stale completion callback. */\nfunction stopCurrentLayout(state: GraphRuntimeState) {\n state.generationRef.current += 1;\n state.layoutRunningRef.current = false;\n state.layoutRef.current?.stop();\n state.layoutRef.current = null;\n}\n\n/*** Apply consumer styles and hide native node paint only when React rich nodes are active. */\nfunction applyGraphStyles(\n cy: Core,\n rules: readonly GraphViewStyleRule[] | undefined,\n richNodeRendering: boolean,\n) {\n const styles = [...(rules ?? [])];\n if (richNodeRendering) {\n styles.push({\n selector: 'node',\n style: {\n 'background-opacity': 0,\n 'border-width': 0,\n label: '',\n 'overlay-opacity': 0,\n },\n });\n }\n if (styles.length > 0) cy.style(styles).update();\n}\n\n/***\n * Synchronize controlled selection without rerunning layout.\n * Selection updates must not trigger graph reconstruction or layout.\n */\nfunction setSelectedNodeIds(state: GraphRuntimeState, nodeIds: readonly string[] | undefined) {\n if (state.cy.destroyed() || nodeIds === undefined) return;\n const selectedIds = new Set(nodeIds);\n state.cy.nodes().forEach((node) => {\n if (selectedIds.has(node.id())) node.select();\n else node.unselect();\n });\n emitRenderedNodes(state);\n}\n\n/***\n * Persist one rich-node size and schedule at most one relayout for changed geometry.\n * Ignore unchanged measurements before scheduling layout work.\n */\nfunction setNodeSize(state: GraphRuntimeState, id: string, size: GraphViewSize) {\n const previous = state.nodeSizes.get(id);\n if (previous?.width === size.width && previous.height === size.height) return;\n state.nodeSizes.set(id, size);\n applyNodeSize(state.cy, id, size);\n scheduleMeasuredNodeRelayout(state);\n}\n\n/*** Apply every known rich-node size after Cytoscape elements are replaced. */\nfunction applyKnownNodeSizes(state: GraphRuntimeState) {\n for (const [id, size] of state.nodeSizes) applyNodeSize(state.cy, id, size);\n}\n\n/*** Apply one measured model-space size as a Cytoscape per-node style bypass. */\nfunction applyNodeSize(cy: Core, id: string, size: GraphViewSize) {\n const node = cy.getElementById(id);\n if (node.empty()) return;\n node.style({ height: size.height, width: size.width });\n}\n\n/***\n * Coalesce DOM measurements into one follow-up layout generation.\n * Keep one scheduled layout per frame instead of one per measured node.\n */\nfunction scheduleMeasuredNodeRelayout(state: GraphRuntimeState) {\n if (state.relayoutScheduledRef.current) return;\n state.relayoutScheduledRef.current = true;\n scheduleGraphFrame(() => {\n state.relayoutScheduledRef.current = false;\n const input = state.latestUpdateRef.current;\n if (input === null || state.cy.destroyed()) return;\n stopCurrentLayout(state);\n startCurrentLayout(state, input);\n });\n}\n\n/*** Subscribe one React overlay to rendered node state without exposing the Cytoscape core. */\nfunction subscribeRenderedNodes(state: GraphRuntimeState, listener: RenderedNodeListener) {\n state.renderedNodeListeners.add(listener);\n listener(readGraphRenderedNodes(state.cy, state.hoveredNodeIds));\n return () => {\n state.renderedNodeListeners.delete(listener);\n };\n}\n\n/***\n * Publish current rendered node positions only to active rich-node subscribers.\n * Skip snapshot preparation when no overlay is subscribed.\n */\nfunction emitRenderedNodes(\n state: Pick<GraphRuntimeState, 'cy' | 'hoveredNodeIds' | 'renderedNodeListeners'>,\n) {\n if (state.renderedNodeListeners.size === 0) return;\n const nodes = readGraphRenderedNodes(state.cy, state.hoveredNodeIds);\n for (const listener of state.renderedNodeListeners) listener(nodes);\n}\n\n/*** Translate one rich-overlay event back into normal graph selection and callbacks. */\nfunction handleOverlayNodeEvent(\n state: GraphRuntimeState,\n id: string,\n type: GraphViewElementEventType,\n) {\n if (type === 'pointer-enter') state.hoveredNodeIds.add(id);\n if (type === 'pointer-leave') state.hoveredNodeIds.delete(id);\n if (type === 'press') state.cy.getElementById(id).select();\n state.callbacksRef.current.onNodeEvent?.({ id, type });\n emitRenderedNodes(state);\n}\n\n/*** Return whether Cytoscape currently has dimensions suitable for fitting. */\nfunction hasUsableViewport(cy: Core): boolean {\n return cy.width() > 0 && cy.height() > 0;\n}\n\n/*** Dispose all runtime resources in the reverse order they were acquired. */\nfunction destroyRuntime(state: GraphRuntimeState) {\n state.resizeObserver?.disconnect();\n stopCurrentLayout(state);\n state.unbindEvents();\n state.renderedNodeListeners.clear();\n if (!state.cy.destroyed()) state.cy.destroy();\n}\n\nregisterGraphLayouts();\n"]}
|
|
1
|
+
{"version":3,"file":"createGraphRuntime.js","sourceRoot":"","sources":["../../../../../../src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SelectionIntent } from '@ankhorage/utility/selection';\nimport cytoscape, { type Core, type CytoscapeOptions } from 'cytoscape';\n\nimport type {\n GraphViewCallbacks,\n GraphViewElementEventType,\n GraphViewFitOptions,\n GraphViewRenderedNode,\n GraphViewSize,\n GraphViewStyleRule,\n} from '../../../../../types/graph-view';\nimport type { GraphRuntimeUpdate } from '../../../../../types/graphViewRuntime';\nimport { bindGraphEvents } from './bindGraphEvents';\nimport { compactGraphSpacing } from './compactGraphSpacing';\nimport { createGraphController } from './createGraphController';\nimport { createGraphLoopSizer } from './createGraphLoopSizer';\nimport { createGraphResizeObserver, type GraphResizeObserver } from './createGraphResizeObserver';\nimport { getGraphGeometryKey } from './getGraphGeometryKey';\nimport { getGraphTopologyKey } from './getGraphTopologyKey';\nimport { hasGraphLayoutChanged } from './hasGraphLayoutChanged';\nimport { readGraphRenderedNodes } from './readGraphRenderedNodes';\nimport { registerGraphLayouts } from './registerGraphLayouts';\nimport { runGraphLayout } from './runGraphLayout';\nimport { scheduleGraphFrame } from './scheduleGraphFrame';\nimport { shouldFitGraphAfterLayout } from './shouldFitGraphAfterLayout';\nimport { sizeGraphNodesToLabels } from './sizeGraphNodesToLabels';\nimport { syncGraphElements } from './syncGraphElements';\n\ntype GraphContainer = CytoscapeOptions['container'];\ntype RenderedNodeListener = (nodes: readonly GraphViewRenderedNode[]) => void;\n\nexport interface GraphRuntime {\n destroy(): void;\n handleOverlayNodeEvent(\n id: string,\n type: GraphViewElementEventType,\n selectionIntent?: SelectionIntent,\n ): void;\n setNodeSize(id: string, size: GraphViewSize): void;\n setSelectedNodeIds(nodeIds: readonly string[] | undefined): void;\n subscribeRenderedNodes(listener: RenderedNodeListener): () => void;\n update(input: GraphRuntimeUpdate): void;\n}\n\ninterface GraphRuntimeState {\n readonly fitRequestRef: { current: GraphViewFitOptions | null };\n readonly optimizedSpacingRef: { current: number | null };\n readonly callbacksRef: { current: GraphViewCallbacks };\n readonly controller: ReturnType<typeof createGraphController>['controller'];\n readonly viewport: ReturnType<typeof createGraphController>;\n readonly cy: Core;\n readonly fitPaddingRef: { current: number };\n readonly generationRef: { current: number };\n readonly geometryRef: { current: string | null };\n readonly hoveredNodeIds: Set<string>;\n readonly latestUpdateRef: { current: GraphRuntimeUpdate | null };\n readonly layoutRef: { current: ReturnType<typeof runGraphLayout> | null };\n readonly layoutRunningRef: { current: boolean };\n readonly nodeSizes: Map<string, GraphViewSize>;\n readonly labelSizedNodeIds: Set<string>;\n readonly loopSizer: ReturnType<typeof createGraphLoopSizer>;\n readonly pendingInitialFitRef: { current: boolean };\n readonly readyRef: { current: boolean };\n readonly settledTopologyRef: { current: string | null };\n readonly relayoutScheduledRef: { current: boolean };\n readonly renderedNodeListeners: Set<RenderedNodeListener>;\n readonly resizeObserver: GraphResizeObserver | null;\n readonly unbindEvents: () => void;\n}\n\n/*** Create one Cytoscape runtime that exclusively owns layout, fit, resize, and disposal. */\nexport function createGraphRuntime(\n container: GraphContainer,\n callbacksRef: { current: GraphViewCallbacks },\n): GraphRuntime {\n const cy = cytoscape({\n container,\n elements: [],\n minZoom: 0.05,\n maxZoom: 2,\n selectionType: 'additive',\n userPanningEnabled: true,\n });\n const state = createRuntimeState(cy, container, callbacksRef);\n\n return {\n destroy: () => destroyRuntime(state),\n handleOverlayNodeEvent: (id, type, selectionIntent) =>\n handleOverlayNodeEvent(state, id, type, selectionIntent),\n setNodeSize: (id, size) => setNodeSize(state, id, size),\n setSelectedNodeIds: (nodeIds) => setSelectedNodeIds(state, nodeIds),\n subscribeRenderedNodes: (listener) => subscribeRenderedNodes(state, listener),\n update: (input) => updateRuntime(state, input),\n };\n}\n\n/*** Build the mutable state shared by the single graph-runtime owner. */\nfunction createRuntimeState(\n cy: Core,\n container: GraphContainer,\n callbacksRef: { current: GraphViewCallbacks },\n): GraphRuntimeState {\n const fitPaddingRef = { current: 50 };\n const viewport = createGraphController(cy, fitPaddingRef, (options) =>\n requestOptimizedFit(state, options),\n );\n const { controller } = viewport;\n const layoutRunningRef = { current: false };\n const readyRef = { current: false };\n const renderedNodeListeners = new Set<RenderedNodeListener>();\n const stateBase = {\n fitRequestRef: { current: null as GraphViewFitOptions | null },\n optimizedSpacingRef: { current: null as number | null },\n callbacksRef,\n controller,\n viewport,\n cy,\n fitPaddingRef,\n generationRef: { current: 0 },\n geometryRef: { current: null as string | null },\n hoveredNodeIds: new Set<string>(),\n latestUpdateRef: { current: null as GraphRuntimeUpdate | null },\n layoutRef: { current: null as ReturnType<typeof runGraphLayout> | null },\n layoutRunningRef,\n nodeSizes: new Map<string, GraphViewSize>(),\n labelSizedNodeIds: new Set<string>(),\n loopSizer: createGraphLoopSizer(cy),\n pendingInitialFitRef: { current: false },\n readyRef,\n settledTopologyRef: { current: null as string | null },\n relayoutScheduledRef: { current: false },\n renderedNodeListeners,\n };\n const unbindEvents = bindGraphEvents(cy, callbacksRef, controller, () =>\n emitRenderedNodes(stateBase),\n );\n const resizeObserver = createGraphResizeObserver({\n container,\n cy,\n settleViewport: () => viewport.settle(true),\n layoutRunningRef,\n pendingInitialFitRef: stateBase.pendingInitialFitRef,\n onViewportSettled: (completedPendingInitialFit) => {\n emitRenderedNodes(stateBase);\n if (!completedPendingInitialFit || readyRef.current) return;\n readyRef.current = true;\n callbacksRef.current.onReady?.(controller);\n callbacksRef.current.onLayoutComplete?.(controller);\n },\n readyRef,\n });\n\n const state = { ...stateBase, resizeObserver, unbindEvents };\n return state;\n}\n\n/***\n * Reconcile presentation in place and relayout only when graph geometry or layout policy changes.\n * Batch reconciliation and skip layout for presentation-only updates.\n */\nfunction updateRuntime(state: GraphRuntimeState, input: GraphRuntimeUpdate) {\n if (state.cy.destroyed()) return;\n const last = state.latestUpdateRef.current;\n const acceptsSpacing =\n state.optimizedSpacingRef.current !== null &&\n state.optimizedSpacingRef.current === input.spacingFactor;\n const previous = acceptsSpacing && last ? { ...last, spacingFactor: input.spacingFactor } : last;\n if (acceptsSpacing) state.optimizedSpacingRef.current = null;\n state.latestUpdateRef.current = input;\n state.fitPaddingRef.current = input.fitPadding ?? 50;\n state.viewport.configure(input);\n state.cy.batch(() => {\n if (previous?.nodes !== input.nodes || previous.edges !== input.edges) {\n syncGraphElements(state.cy, input.nodes, input.edges);\n }\n if (\n previous?.styleRules !== input.styleRules ||\n previous?.richNodeRendering !== input.richNodeRendering\n ) {\n state.loopSizer.reset();\n applyGraphStyles(state.cy, input.styleRules, input.richNodeRendering);\n }\n });\n sizeGraphNodesToLabels(\n state.cy,\n state.labelSizedNodeIds,\n input.sizeNodesToLabels === true && !input.richNodeRendering,\n );\n applyKnownNodeSizes(state);\n state.loopSizer.update();\n const geometry = getGraphGeometryKey(state.cy);\n const relayout = geometry !== state.geometryRef.current || hasGraphLayoutChanged(previous, input);\n state.geometryRef.current = geometry;\n if (!relayout) {\n if (\n previous?.zoomMode !== input.zoomMode ||\n previous?.fitPadding !== input.fitPadding ||\n previous?.minZoom !== input.minZoom ||\n previous?.maxZoom !== input.maxZoom ||\n previous?.minReadableLabelSize !== input.minReadableLabelSize ||\n previous?.maxFitLabelSize !== input.maxFitLabelSize\n ) {\n state.viewport.settle(previous?.zoomMode !== input.zoomMode);\n }\n emitRenderedNodes(state);\n if (!state.layoutRunningRef.current && !state.pendingInitialFitRef.current)\n state.callbacksRef.current.onLayoutComplete?.(state.controller);\n return;\n }\n stopCurrentLayout(state);\n state.fitRequestRef.current = null;\n state.optimizedSpacingRef.current = null;\n startCurrentLayout(state, input);\n}\n\n/*** Start a generation-safe layout whose completion is the only normal automatic fit trigger. */\nfunction startCurrentLayout(state: GraphRuntimeState, input: GraphRuntimeUpdate) {\n state.pendingInitialFitRef.current = false;\n const generation = state.generationRef.current + 1;\n state.generationRef.current = generation;\n state.layoutRunningRef.current = true;\n state.cy.resize();\n state.layoutRef.current = runGraphLayout(\n state.cy,\n {\n layout: input.layout ?? 'concentric',\n layoutOptions: input.layoutOptions,\n spacingFactor: input.spacingFactor ?? 1,\n },\n () => completeCurrentLayout(state, generation),\n );\n}\n\n/***\n * Settle only the latest layout generation and fit once from node bounds.\n * Discard stale completions and avoid repeated automatic fits.\n */\nfunction completeCurrentLayout(state: GraphRuntimeState, generation: number) {\n scheduleGraphFrame(() => {\n if (state.cy.destroyed() || generation !== state.generationRef.current) return;\n state.loopSizer.update();\n state.layoutRef.current = null;\n state.cy.resize();\n state.layoutRunningRef.current = false;\n if (!hasUsableViewport(state.cy)) {\n if (!state.readyRef.current) state.pendingInitialFitRef.current = true;\n return;\n }\n state.pendingInitialFitRef.current = false;\n const input = state.latestUpdateRef.current;\n if (input === null) return;\n const topology = getGraphTopologyKey(input.nodes, input.edges);\n const shouldFit = shouldFitGraphAfterLayout(\n state.readyRef.current,\n topology !== state.settledTopologyRef.current,\n );\n state.viewport.settle(shouldFit);\n state.settledTopologyRef.current = topology;\n const fitRequest = state.fitRequestRef.current;\n state.fitRequestRef.current = null;\n if (fitRequest) requestOptimizedFit(state, fitRequest);\n emitRenderedNodes(state);\n\n if (!state.readyRef.current) {\n state.readyRef.current = true;\n state.callbacksRef.current.onReady?.(state.controller);\n }\n state.callbacksRef.current.onLayoutComplete?.(state.controller);\n });\n}\n\n/***\n * Handle explicit readable-fit intent in the runtime owner, never from zoom or React effects.\n * Bounded spacing optimization preserves the settled algorithm instead of repeatedly running it.\n */\nfunction requestOptimizedFit(state: GraphRuntimeState, options: GraphViewFitOptions) {\n if (state.cy.destroyed()) return;\n if (state.layoutRunningRef.current) {\n state.fitRequestRef.current = options;\n return;\n }\n const input = state.latestUpdateRef.current;\n if (!input) return;\n const previous = state.optimizedSpacingRef.current ?? input.spacingFactor ?? 1;\n const spacing = compactGraphSpacing(state.cy, previous, {\n fitPadding: options.padding ?? state.fitPaddingRef.current,\n maxFitZoom: state.viewport.getFitZoomLimit(),\n minReadableZoom: state.viewport.getReadableZoomTarget(),\n });\n state.geometryRef.current = getGraphGeometryKey(state.cy);\n state.loopSizer.update();\n state.viewport.settle(false);\n state.controller.fit({ ...options, optimizeSpacing: false });\n if (spacing !== previous) {\n state.optimizedSpacingRef.current = spacing;\n state.callbacksRef.current.onSpacingFactorChange?.(spacing);\n }\n emitRenderedNodes(state);\n}\n\n/*** Stop the current layout and invalidate every stale completion callback. */\nfunction stopCurrentLayout(state: GraphRuntimeState) {\n state.generationRef.current += 1;\n state.layoutRunningRef.current = false;\n state.layoutRef.current?.stop();\n state.layoutRef.current = null;\n}\n\n/*** Apply consumer styles and hide native node paint only when React rich nodes are active. */\nfunction applyGraphStyles(\n cy: Core,\n rules: readonly GraphViewStyleRule[] | undefined,\n richNodeRendering: boolean,\n) {\n const styles = [...(rules ?? [])];\n if (richNodeRendering) {\n styles.push({\n selector: 'node',\n style: {\n 'background-opacity': 0,\n 'border-width': 0,\n label: '',\n 'overlay-opacity': 0,\n },\n });\n }\n if (styles.length > 0) cy.style(styles).update();\n}\n\n/***\n * Synchronize controlled selection without rerunning layout.\n * Selection updates must not trigger graph reconstruction or layout.\n */\nfunction setSelectedNodeIds(state: GraphRuntimeState, nodeIds: readonly string[] | undefined) {\n if (state.cy.destroyed() || nodeIds === undefined) return;\n const selectedIds = new Set(nodeIds);\n state.cy.nodes().forEach((node) => {\n if (selectedIds.has(node.id())) node.select();\n else node.unselect();\n });\n emitRenderedNodes(state);\n}\n\n/***\n * Persist one rich-node size and schedule at most one relayout for changed geometry.\n * Ignore unchanged measurements before scheduling layout work.\n */\nfunction setNodeSize(state: GraphRuntimeState, id: string, size: GraphViewSize) {\n const previous = state.nodeSizes.get(id);\n if (previous?.width === size.width && previous.height === size.height) return;\n state.nodeSizes.set(id, size);\n applyNodeSize(state.cy, id, size);\n scheduleMeasuredNodeRelayout(state);\n}\n\n/*** Apply every known rich-node size after Cytoscape elements are replaced. */\nfunction applyKnownNodeSizes(state: GraphRuntimeState) {\n for (const [id, size] of state.nodeSizes) applyNodeSize(state.cy, id, size);\n}\n\n/*** Apply one measured model-space size as a Cytoscape per-node style bypass. */\nfunction applyNodeSize(cy: Core, id: string, size: GraphViewSize) {\n const node = cy.getElementById(id);\n if (node.empty()) return;\n node.style({ height: size.height, width: size.width });\n}\n\n/***\n * Coalesce DOM measurements into one follow-up layout generation.\n * Keep one scheduled layout per frame instead of one per measured node.\n */\nfunction scheduleMeasuredNodeRelayout(state: GraphRuntimeState) {\n if (state.relayoutScheduledRef.current) return;\n state.relayoutScheduledRef.current = true;\n scheduleGraphFrame(() => {\n state.relayoutScheduledRef.current = false;\n const input = state.latestUpdateRef.current;\n if (input === null || state.cy.destroyed()) return;\n stopCurrentLayout(state);\n startCurrentLayout(state, input);\n });\n}\n\n/*** Subscribe one React overlay to rendered node state without exposing the Cytoscape core. */\nfunction subscribeRenderedNodes(state: GraphRuntimeState, listener: RenderedNodeListener) {\n state.renderedNodeListeners.add(listener);\n listener(readGraphRenderedNodes(state.cy, state.hoveredNodeIds));\n return () => {\n state.renderedNodeListeners.delete(listener);\n };\n}\n\n/***\n * Publish current rendered node positions only to active rich-node subscribers.\n * Skip snapshot preparation when no overlay is subscribed.\n */\nfunction emitRenderedNodes(\n state: Pick<GraphRuntimeState, 'cy' | 'hoveredNodeIds' | 'renderedNodeListeners'>,\n) {\n if (state.renderedNodeListeners.size === 0) return;\n const nodes = readGraphRenderedNodes(state.cy, state.hoveredNodeIds);\n for (const listener of state.renderedNodeListeners) listener(nodes);\n}\n\n/*** Translate one rich-overlay event back into normal graph selection and callbacks. */\nfunction handleOverlayNodeEvent(\n state: GraphRuntimeState,\n id: string,\n type: GraphViewElementEventType,\n selectionIntent?: SelectionIntent,\n) {\n if (type === 'pointer-enter') state.hoveredNodeIds.add(id);\n if (type === 'pointer-leave') state.hoveredNodeIds.delete(id);\n if (type === 'press') state.cy.getElementById(id).select();\n state.callbacksRef.current.onNodeEvent?.({ id, type, selectionIntent });\n emitRenderedNodes(state);\n}\n\n/*** Return whether Cytoscape currently has dimensions suitable for fitting. */\nfunction hasUsableViewport(cy: Core): boolean {\n return cy.width() > 0 && cy.height() > 0;\n}\n\n/*** Dispose all runtime resources in the reverse order they were acquired. */\nfunction destroyRuntime(state: GraphRuntimeState) {\n state.resizeObserver?.disconnect();\n stopCurrentLayout(state);\n state.unbindEvents();\n state.renderedNodeListeners.clear();\n if (!state.cy.destroyed()) state.cy.destroy();\n}\n\nregisterGraphLayouts();\n"]}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { SelectableItemProps } from '../../../../types/selection';
|
|
3
|
-
/***
|
|
4
|
-
* Adds selection behavior to arbitrary child content via render props.
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
*/
|
|
3
|
+
/*** Adds selection behavior to arbitrary child content via render props. */
|
|
8
4
|
export declare function SelectableItem({ id, trigger, disabled, interactionPolicy, children, }: SelectableItemProps): React.JSX.Element;
|
|
9
5
|
//# sourceMappingURL=SelectableItem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectableItem.d.ts","sourceRoot":"","sources":["../../../../../src/features/selection/adapters/inbound/SelectableItem.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SelectableItem.d.ts","sourceRoot":"","sources":["../../../../../src/features/selection/adapters/inbound/SelectableItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,6BAA6B,CAAC;AAgBrC,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,EAC7B,EAAE,EACF,OAAO,EACP,QAAgB,EAChB,iBAAiB,EACjB,QAAQ,GACT,EAAE,mBAAmB,qBAgErB"}
|
|
@@ -1,86 +1,62 @@
|
|
|
1
1
|
import { Pressable } from '@ankhorage/surface';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
import { resolveSelectionEventIntent } from '../../application/resolveSelectionEventIntent';
|
|
3
5
|
import { useSelection } from './SelectionProvider';
|
|
6
|
+
/*** Resolve the configured selection trigger. */
|
|
4
7
|
function resolveTrigger(trigger) {
|
|
5
8
|
return trigger ?? 'manual';
|
|
6
9
|
}
|
|
10
|
+
/*** Narrow render-prop children without changing ordinary React-node children. */
|
|
7
11
|
function isRenderProp(children) {
|
|
8
12
|
return typeof children === 'function';
|
|
9
13
|
}
|
|
10
|
-
/***
|
|
11
|
-
* Adds selection behavior to arbitrary child content via render props.
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
*/
|
|
14
|
+
/*** Adds selection behavior to arbitrary child content via render props. */
|
|
15
15
|
export function SelectableItem({ id, trigger, disabled = false, interactionPolicy, children, }) {
|
|
16
16
|
const selection = useSelection();
|
|
17
17
|
const resolvedTrigger = resolveTrigger(trigger);
|
|
18
18
|
const resolvedDisabled = selection.disabled || disabled;
|
|
19
19
|
const selected = selection.isSelected(id);
|
|
20
|
-
const
|
|
21
|
-
if (resolvedDisabled)
|
|
20
|
+
const activate = React.useCallback((intent) => {
|
|
21
|
+
if (resolvedDisabled || interactionPolicy === 'passive')
|
|
22
22
|
return;
|
|
23
|
-
|
|
23
|
+
selection.activate(id, intent);
|
|
24
|
+
}, [id, interactionPolicy, resolvedDisabled, selection]);
|
|
25
|
+
const select = React.useCallback(() => {
|
|
26
|
+
if (resolvedDisabled || interactionPolicy === 'passive')
|
|
24
27
|
return;
|
|
25
28
|
selection.select(id);
|
|
26
|
-
}, [id,
|
|
29
|
+
}, [id, interactionPolicy, resolvedDisabled, selection]);
|
|
27
30
|
const toggle = React.useCallback(() => {
|
|
28
|
-
if (resolvedDisabled)
|
|
29
|
-
return;
|
|
30
|
-
if (interactionPolicy === 'passive')
|
|
31
|
+
if (resolvedDisabled || interactionPolicy === 'passive')
|
|
31
32
|
return;
|
|
32
33
|
selection.toggle(id);
|
|
33
|
-
}, [id,
|
|
34
|
+
}, [id, interactionPolicy, resolvedDisabled, selection]);
|
|
34
35
|
const clear = React.useCallback(() => {
|
|
35
|
-
if (selection.disabled)
|
|
36
|
-
return;
|
|
37
|
-
if (interactionPolicy === 'passive')
|
|
36
|
+
if (selection.disabled || interactionPolicy === 'passive')
|
|
38
37
|
return;
|
|
39
38
|
selection.clear();
|
|
40
39
|
}, [interactionPolicy, selection]);
|
|
41
|
-
const itemState = React.useMemo(() => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}, [clear, id, resolvedDisabled, select, selected, selection.mode, toggle]);
|
|
52
|
-
// IMPORTANT:
|
|
53
|
-
// Do not pass `children` directly into Pressable. Pressable also supports function children,
|
|
54
|
-
// but its function signature receives interaction state, not SelectableItemState.
|
|
40
|
+
const itemState = React.useMemo(() => ({
|
|
41
|
+
id,
|
|
42
|
+
selected,
|
|
43
|
+
disabled: resolvedDisabled,
|
|
44
|
+
mode: selection.mode,
|
|
45
|
+
activate,
|
|
46
|
+
select,
|
|
47
|
+
toggle,
|
|
48
|
+
clear,
|
|
49
|
+
}), [activate, clear, id, resolvedDisabled, select, selected, selection.mode, toggle]);
|
|
55
50
|
const content = isRenderProp(children) ? children(itemState) : children;
|
|
56
|
-
if (resolvedTrigger === 'manual')
|
|
51
|
+
if (resolvedTrigger === 'manual')
|
|
57
52
|
return <>{content}</>;
|
|
58
|
-
|
|
59
|
-
const handlePress = (event) => {
|
|
53
|
+
const handleActivation = (event) => {
|
|
60
54
|
event.stopPropagation();
|
|
61
|
-
if (resolvedDisabled)
|
|
55
|
+
if (resolvedDisabled || interactionPolicy === 'passive')
|
|
62
56
|
return;
|
|
63
|
-
|
|
64
|
-
return;
|
|
65
|
-
if (selection.mode === 'single') {
|
|
66
|
-
selection.select(id);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
selection.toggle(id);
|
|
70
|
-
};
|
|
71
|
-
const handleLongPress = (event) => {
|
|
72
|
-
event.stopPropagation();
|
|
73
|
-
if (resolvedDisabled)
|
|
74
|
-
return;
|
|
75
|
-
if (interactionPolicy === 'passive')
|
|
76
|
-
return;
|
|
77
|
-
if (selection.mode === 'single') {
|
|
78
|
-
selection.select(id);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
selection.toggle(id);
|
|
57
|
+
selection.activate(id, resolveSelectionEventIntent(event, Platform.OS === 'web' ? 'pointer' : 'touch'));
|
|
82
58
|
};
|
|
83
|
-
return (<Pressable interactionPolicy={interactionPolicy} accessibilityRole="button" accessibilityState={{ disabled: resolvedDisabled, selected }} disabled={resolvedDisabled} onLongPress={resolvedTrigger === 'longPress' ?
|
|
59
|
+
return (<Pressable interactionPolicy={interactionPolicy} accessibilityRole="button" accessibilityState={{ disabled: resolvedDisabled, selected }} disabled={resolvedDisabled} onLongPress={resolvedTrigger === 'longPress' ? handleActivation : undefined} onPress={resolvedTrigger === 'press' ? handleActivation : undefined}>
|
|
84
60
|
{content}
|
|
85
61
|
</Pressable>);
|
|
86
62
|
}
|