@ankhorage/zora 25.8.11 → 25.8.13
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 +2 -1
- package/dist/features/grid-interactions/adapters/inbound/GridInteractions.d.ts.map +1 -1
- package/dist/features/grid-interactions/adapters/inbound/GridInteractions.js +11 -2
- package/dist/features/grid-interactions/adapters/inbound/GridInteractions.js.map +1 -1
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.d.ts.map +1 -1
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js +9 -2
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js.map +1 -1
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.d.ts +2 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.js +2 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.js.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.d.ts +4 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.js +11 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.js.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.d.ts +4 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.js +9 -0
- package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.js.map +1 -0
- package/dist/features/grid-interactions/application/createGridInteractionScrollLock.d.ts +5 -0
- package/dist/features/grid-interactions/application/createGridInteractionScrollLock.d.ts.map +1 -0
- package/dist/features/grid-interactions/application/createGridInteractionScrollLock.js +14 -0
- package/dist/features/grid-interactions/application/createGridInteractionScrollLock.js.map +1 -0
- package/dist/features/grid-view/adapters/inbound/GridView.d.ts.map +1 -1
- package/dist/features/grid-view/adapters/inbound/GridView.js +34 -30
- package/dist/features/grid-view/adapters/inbound/GridView.js.map +1 -1
- package/dist/features/grid-view/application/createGridScrollSync.d.ts +7 -0
- package/dist/features/grid-view/application/createGridScrollSync.d.ts.map +1 -0
- package/dist/features/grid-view/application/createGridScrollSync.js +141 -0
- package/dist/features/grid-view/application/createGridScrollSync.js.map +1 -0
- package/dist/features/grid-view/application/resolveScrollEventSource.d.ts +4 -0
- package/dist/features/grid-view/application/resolveScrollEventSource.d.ts.map +1 -0
- package/dist/features/grid-view/application/resolveScrollEventSource.js +8 -0
- package/dist/features/grid-view/application/resolveScrollEventSource.js.map +1 -0
- package/dist/features/grid-view/constants/scroll.d.ts +7 -0
- package/dist/features/grid-view/constants/scroll.d.ts.map +1 -0
- package/dist/features/grid-view/constants/scroll.js +7 -0
- package/dist/features/grid-view/constants/scroll.js.map +1 -0
- package/dist/features/layout/adapters/inbound/ScrollGestureLockContext.d.ts +5 -0
- package/dist/features/layout/adapters/inbound/ScrollGestureLockContext.d.ts.map +1 -0
- package/dist/features/layout/adapters/inbound/ScrollGestureLockContext.js +4 -0
- package/dist/features/layout/adapters/inbound/ScrollGestureLockContext.js.map +1 -0
- package/dist/features/layout/adapters/inbound/ScrollView.d.ts.map +1 -1
- package/dist/features/layout/adapters/inbound/ScrollView.js +11 -3
- package/dist/features/layout/adapters/inbound/ScrollView.js.map +1 -1
- package/dist/features/layout/adapters/inbound/useScrollGestureLock.d.ts +4 -0
- package/dist/features/layout/adapters/inbound/useScrollGestureLock.d.ts.map +1 -0
- package/dist/features/layout/adapters/inbound/useScrollGestureLock.js +8 -0
- package/dist/features/layout/adapters/inbound/useScrollGestureLock.js.map +1 -0
- package/dist/features/layout/public.d.ts +2 -1
- package/dist/features/layout/public.d.ts.map +1 -1
- package/dist/features/layout/public.js +1 -0
- package/dist/features/layout/public.js.map +1 -1
- package/dist/features/layout/utils/createScrollGestureLock.d.ts +4 -0
- package/dist/features/layout/utils/createScrollGestureLock.d.ts.map +1 -0
- package/dist/features/layout/utils/createScrollGestureLock.js +18 -0
- package/dist/features/layout/utils/createScrollGestureLock.js.map +1 -0
- package/dist/types/grid-interactions.d.ts +5 -0
- package/dist/types/grid-interactions.d.ts.map +1 -1
- package/dist/types/grid-interactions.js.map +1 -1
- package/dist/types/grid-view.d.ts +40 -0
- package/dist/types/grid-view.d.ts.map +1 -1
- package/dist/types/grid-view.js.map +1 -1
- package/dist/types/layout.d.ts +5 -0
- package/dist/types/layout.d.ts.map +1 -1
- package/dist/types/layout.js.map +1 -1
- package/package.json +2 -2
- package/src/features/grid-interactions/adapters/inbound/GridInteractions.scrollLock.test.tsx +265 -0
- package/src/features/grid-interactions/adapters/inbound/GridInteractions.test.tsx +70 -1
- package/src/features/grid-interactions/adapters/inbound/GridInteractions.tsx +12 -5
- package/src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.tsx +10 -1
- package/src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.ts +17 -0
- package/src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.ts +1 -0
- package/src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.ts +11 -0
- package/src/features/grid-interactions/application/createGridInteractionScrollLock.test.ts +41 -0
- package/src/features/grid-interactions/application/createGridInteractionScrollLock.ts +18 -0
- package/src/features/grid-view/adapters/inbound/GridView.nativeScrollSync.test.tsx +186 -0
- package/src/features/grid-view/adapters/inbound/GridView.scrollSync.interaction.test.tsx +304 -0
- package/src/features/grid-view/adapters/inbound/GridView.tsx +49 -29
- package/src/features/grid-view/application/createGridScrollSync.test.ts +292 -0
- package/src/features/grid-view/application/createGridScrollSync.ts +169 -0
- package/src/features/grid-view/application/resolveScrollEventSource.test.ts +19 -0
- package/src/features/grid-view/application/resolveScrollEventSource.ts +12 -0
- package/src/features/grid-view/constants/scroll.ts +8 -0
- package/src/features/layout/adapters/inbound/ScrollGestureLockContext.ts +8 -0
- package/src/features/layout/adapters/inbound/ScrollView.test.tsx +234 -0
- package/src/features/layout/adapters/inbound/ScrollView.tsx +18 -2
- package/src/features/layout/adapters/inbound/useScrollGestureLock.ts +11 -0
- package/src/features/layout/public.ts +2 -0
- package/src/features/layout/utils/createScrollGestureLock.test.ts +34 -0
- package/src/features/layout/utils/createScrollGestureLock.ts +21 -0
- package/src/types/grid-interactions.ts +6 -0
- package/src/types/grid-view.ts +45 -0
- package/src/types/layout.ts +6 -0
- package/web-dist/chunks/{Accordion-v3rzy273.js → Accordion-11ej93t5.js} +3 -3
- package/web-dist/chunks/{Accordion-ddrn94v3.js → Accordion-1hbt9k69.js} +1 -1
- package/web-dist/chunks/{Accordion-wpk8dxqp.js → Accordion-26prtnm7.js} +1 -1
- package/web-dist/chunks/{Accordion-0q2wzjdd.js → Accordion-2jy53kzk.js} +2 -2
- package/web-dist/chunks/{Accordion-geah5s4f.js → Accordion-4yq92mxp.js} +1 -1
- package/web-dist/chunks/{Accordion-8pkw32q9.js → Accordion-5pr1wqe3.js} +1 -1
- package/web-dist/chunks/{Accordion-y3083394.js → Accordion-799z2zf6.js} +1 -1
- package/web-dist/chunks/{Accordion-hecpczme.js → Accordion-9aczb0k2.js} +2 -2
- package/web-dist/chunks/{Accordion-rctfgyfv.js → Accordion-a4pz3vjj.js} +1 -1
- package/web-dist/chunks/{Accordion-9jrxktne.js → Accordion-b337t2df.js} +1 -1
- package/web-dist/chunks/{Accordion-h4ekm5cp.js → Accordion-czcaf5x2.js} +1 -1
- package/web-dist/chunks/{Accordion-vbzjq3z8.js → Accordion-ep35792s.js} +44 -2
- package/web-dist/chunks/{Accordion-ts788t7b.js → Accordion-g08740h4.js} +1 -1
- package/web-dist/chunks/{Accordion-9ygakvwk.js → Accordion-g2aqhct0.js} +4 -4
- package/web-dist/chunks/{Accordion-p1ebrt17.js → Accordion-gn8ptzwb.js} +1 -1
- package/web-dist/chunks/{Accordion-sq7ya2ye.js → Accordion-h9brgsk8.js} +1 -1
- package/web-dist/chunks/{Accordion-ztw7zp6v.js → Accordion-m2hcc8g4.js} +2 -2
- package/web-dist/chunks/{Accordion-sdnzqktc.js → Accordion-m6mp8aea.js} +3 -3
- package/web-dist/chunks/{Accordion-vxg5sw01.js → Accordion-p7d5svfq.js} +1 -1
- package/web-dist/chunks/{Accordion-k9cxpg08.js → Accordion-rqhh2m5b.js} +3 -3
- package/web-dist/chunks/{Accordion-wcmrasqx.js → Accordion-rqr10gn4.js} +4 -4
- package/web-dist/chunks/{Accordion-hn43wt45.js → Accordion-t0k1cjca.js} +181 -29
- package/web-dist/chunks/{Accordion-w59y0jdf.js → Accordion-tyh8jj9d.js} +1 -1
- package/web-dist/chunks/{Accordion-dk0dtyc0.js → Accordion-vjcd5kxc.js} +1 -1
- package/web-dist/chunks/{Accordion-t5scffdr.js → Accordion-vkd002gw.js} +5 -5
- package/web-dist/chunks/{Accordion-r87xx7mg.js → Accordion-w87gvpbg.js} +1 -1
- package/web-dist/chunks/{Accordion-yexfbrzg.js → Accordion-wqyrrptg.js} +2 -2
- package/web-dist/chunks/{Accordion-c50pywj3.js → Accordion-y2pss5p0.js} +1 -1
- package/web-dist/components/accordion/Accordion.js +2 -2
- package/web-dist/components/accordion-item/AccordionItem.js +2 -2
- package/web-dist/components/app-bar/AppBar.js +4 -4
- package/web-dist/components/app-header/AppHeader.js +4 -4
- package/web-dist/components/app-shell/AppShell.js +1 -1
- package/web-dist/components/auth-screen/AuthScreen.js +6 -6
- package/web-dist/components/avatar/Avatar.js +2 -2
- package/web-dist/components/avatar-group/AvatarGroup.js +2 -2
- package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +6 -6
- package/web-dist/components/bottom-sheet/BottomSheet.js +2 -2
- package/web-dist/components/bottom-sheet-flat-list/BottomSheetFlatList.js +2 -2
- package/web-dist/components/bottom-sheet-scroll-view/BottomSheetScrollView.js +2 -2
- package/web-dist/components/bottom-sheet-section-list/BottomSheetSectionList.js +2 -2
- package/web-dist/components/bottom-sheet-view/BottomSheetView.js +2 -2
- package/web-dist/components/bottom-sheet-virtualized-list/BottomSheetVirtualizedList.js +2 -2
- package/web-dist/components/breadcrumbs/Breadcrumbs.js +2 -2
- package/web-dist/components/button/Button.js +2 -2
- package/web-dist/components/button-group/ButtonGroup.js +2 -2
- package/web-dist/components/camera-permission-view/CameraPermissionView.js +6 -6
- package/web-dist/components/card/Card.js +5 -5
- package/web-dist/components/chat-list-item/ChatListItem.js +3 -3
- package/web-dist/components/checkbox/Checkbox.js +2 -2
- package/web-dist/components/checkbox-group/CheckboxGroup.js +2 -2
- package/web-dist/components/chip/Chip.js +2 -2
- package/web-dist/components/chip-group/ChipGroup.js +2 -2
- package/web-dist/components/collection-editor/CollectionEditor.js +5 -5
- package/web-dist/components/content-rail/ContentRail.js +2 -2
- package/web-dist/components/data-table/DataTable.js +10 -10
- package/web-dist/components/date-picker/DatePicker.js +2 -2
- package/web-dist/components/dialog/Dialog.js +2 -2
- package/web-dist/components/divider/Divider.js +1 -1
- package/web-dist/components/empty-state/EmptyState.js +6 -6
- package/web-dist/components/explorer/Explorer.js +4 -4
- package/web-dist/components/field/Field.js +2 -2
- package/web-dist/components/file-explorer/FileExplorer.js +4 -4
- package/web-dist/components/flat-list/FlatList.js +3 -3
- package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +6 -6
- package/web-dist/components/form/Form.js +4 -4
- package/web-dist/components/form-actions/FormActions.js +4 -4
- package/web-dist/components/form-error/FormError.js +4 -4
- package/web-dist/components/game/Game.js +2 -2
- package/web-dist/components/game-entity/GameEntity.js +2 -2
- package/web-dist/components/game-field/GameField.js +2 -2
- package/web-dist/components/game-input-zone/GameInputZone.js +2 -2
- package/web-dist/components/game-measurement-probe/GameMeasurementProbe.js +2 -2
- package/web-dist/components/game-overlay/GameOverlay.js +2 -2
- package/web-dist/components/gradient/Gradient.js +2 -2
- package/web-dist/components/gradient-renderer-provider/GradientRendererProvider.js +2 -2
- package/web-dist/components/grid/Grid.js +1 -1
- package/web-dist/components/grid-interactions/GridInteractions.js +33 -4
- package/web-dist/components/grid-view/GridView.js +1 -1
- package/web-dist/components/hero/Hero.js +5 -5
- package/web-dist/components/icon-button/IconButton.js +2 -2
- package/web-dist/components/image/Image.js +2 -2
- package/web-dist/components/list/List.js +3 -3
- package/web-dist/components/list-item/ListItem.js +3 -3
- package/web-dist/components/list-section/ListSection.js +3 -3
- package/web-dist/components/matrix-grid/MatrixGrid.js +1 -1
- package/web-dist/components/media-card/MediaCard.js +5 -5
- package/web-dist/components/media-explorer/MediaExplorer.js +4 -4
- package/web-dist/components/message-bubble/MessageBubble.js +3 -3
- package/web-dist/components/metric-card/MetricCard.js +5 -5
- package/web-dist/components/missing-element/MissingElement.js +1 -1
- package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +6 -6
- package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +6 -6
- package/web-dist/components/otp-form/OtpForm.js +6 -6
- package/web-dist/components/pagination/Pagination.js +2 -2
- package/web-dist/components/palette-item/PaletteItem.js +5 -5
- package/web-dist/components/popover-menu/PopoverMenu.js +2 -2
- package/web-dist/components/post-card/PostCard.js +5 -5
- package/web-dist/components/product-card/ProductCard.js +5 -5
- package/web-dist/components/progress/Progress.js +2 -2
- package/web-dist/components/progress-ring/ProgressRing.js +2 -2
- package/web-dist/components/radio/Radio.js +2 -2
- package/web-dist/components/radio-group/RadioGroup.js +2 -2
- package/web-dist/components/rating/Rating.js +1 -1
- package/web-dist/components/reader/Reader.js +6 -6
- package/web-dist/components/scan-overlay/ScanOverlay.js +6 -6
- package/web-dist/components/screen/Screen.js +1 -1
- package/web-dist/components/screen-section/ScreenSection.js +2 -2
- package/web-dist/components/scroll-view/ScrollView.js +1 -1
- package/web-dist/components/search-input/SearchInput.js +3 -3
- package/web-dist/components/section-header/SectionHeader.js +2 -2
- package/web-dist/components/section-list/SectionList.js +3 -3
- package/web-dist/components/select/Select.js +2 -2
- package/web-dist/components/sign-in-form/SignInForm.js +6 -6
- package/web-dist/components/sign-up-form/SignUpForm.js +6 -6
- package/web-dist/components/skeleton/Skeleton.js +8 -8
- package/web-dist/components/skeleton-card/SkeletonCard.js +8 -8
- package/web-dist/components/skeleton-list/SkeletonList.js +8 -8
- package/web-dist/components/skeleton-text/SkeletonText.js +8 -8
- package/web-dist/components/spatial-grid/SpatialGrid.js +1 -1
- package/web-dist/components/text-input/TextInput.js +3 -3
- package/web-dist/components/tile-grid/TileGrid.js +1 -1
- package/web-dist/components/time-grid/TimeGrid.js +1 -1
- package/web-dist/components/time-picker/TimePicker.js +2 -2
- package/web-dist/components/timeline/Timeline.js +1 -1
- package/web-dist/components/toolbar/Toolbar.js +5 -5
- package/web-dist/components/tree-item/TreeItem.js +4 -4
- package/web-dist/components/uploader/Uploader.js +9 -9
- package/web-dist/components/view/View.js +1 -1
- package/web-dist/manifest.json +326 -326
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 25.8.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- df79c6e: Fix the web grid interaction keyboard boundary so it is reachable through normal tab navigation in browsers.
|
|
8
|
+
|
|
9
|
+
## 25.8.12
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- fe26980: Fix native GridView and GridInteractions gesture ownership. GridView no longer treats native scroll echoes of its own animated focus reveal as user pans, which could sustain an unbounded viewport and render loop in large SpatialGrid boards. GridInteractions now refuses responder termination requests and suspends ancestor ZORA ScrollView scrolling for the duration of an active native drag.
|
|
14
|
+
|
|
3
15
|
## 25.8.11
|
|
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
|
|
|
@@ -65,6 +65,7 @@ This package contains 6 additional examples. See the generated documentation for
|
|
|
65
65
|
- [createPokerTrainingTableState sequence](././paradox/diagrams/sequences/create-poker-training-table-state.mmd)
|
|
66
66
|
- [createZoraThemeConfig sequence](././paradox/diagrams/sequences/create-zora-theme-config.mmd)
|
|
67
67
|
- [getLegalTargets sequence](././paradox/diagrams/sequences/get-legal-targets.mmd)
|
|
68
|
+
- [GridInteractions sequence](././paradox/diagrams/sequences/grid-interactions.mmd)
|
|
68
69
|
- [GridView sequence](././paradox/diagrams/sequences/grid-view.mmd)
|
|
69
70
|
- [readChessPieces sequence](././paradox/diagrams/sequences/read-chess-pieces.mmd)
|
|
70
71
|
- [resolveAvatarInitials sequence](././paradox/diagrams/sequences/resolve-avatar-initials.mmd)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridInteractions.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"GridInteractions.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;AAO7C,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,MAAM,EACN,GAAG,KAAK,EACT,EAAE,qBAAqB,qBAyEvB"}
|
|
@@ -4,6 +4,7 @@ import { createGridInteractionsController } from '../../application/createGridIn
|
|
|
4
4
|
import { createGridInteractionsPointerQueue } from './createGridInteractionsPointerQueue';
|
|
5
5
|
import { GridInteractionsKeyboardProxy } from './GridInteractionsKeyboardProxy';
|
|
6
6
|
import { resolveGridInteractionPointer } from './resolveGridInteractionPointer';
|
|
7
|
+
import { useGridInteractionScrollLock } from './useGridInteractionScrollLock';
|
|
7
8
|
/*** Adapts native responder and keyboard events to the controlled grid interaction boundary. */
|
|
8
9
|
export function GridInteractions({ children, interactionPolicy, resizeHandle, testID, ...props }) {
|
|
9
10
|
const controllerProps = React.useMemo(() => ({ ...props, interactionPolicy }), [interactionPolicy, props]);
|
|
@@ -11,6 +12,7 @@ export function GridInteractions({ children, interactionPolicy, resizeHandle, te
|
|
|
11
12
|
const surfaceRef = React.useRef(null);
|
|
12
13
|
const spaceKeyRef = React.useRef(false);
|
|
13
14
|
const [pointerQueue] = React.useState(() => createGridInteractionsPointerQueue());
|
|
15
|
+
const scrollLock = useGridInteractionScrollLock();
|
|
14
16
|
React.useLayoutEffect(() => controller.update(controllerProps), [controller, controllerProps]);
|
|
15
17
|
React.useLayoutEffect(() => {
|
|
16
18
|
pointerQueue.activate();
|
|
@@ -32,11 +34,18 @@ export function GridInteractions({ children, interactionPolicy, resizeHandle, te
|
|
|
32
34
|
pointerQueue.enqueue(surface, (origin) => handlePointer(resolveGridInteractionPointer(eventSnapshot, origin, modifierSnapshot)));
|
|
33
35
|
};
|
|
34
36
|
const enabled = interactionPolicy !== 'passive';
|
|
35
|
-
return (<View accessible accessibilityLabel="Grid interaction surface"
|
|
37
|
+
return (<View accessible accessibilityLabel="Grid interaction surface" ref={surfaceRef} testID={testID} onResponderGrant={(event) => {
|
|
38
|
+
scrollLock.acquire();
|
|
39
|
+
withPointer(event, (pointer) => controller.begin(pointer, resizeHandle));
|
|
40
|
+
}} onResponderMove={(event) => withPointer(event, controller.move)} onResponderRelease={(event) => {
|
|
41
|
+
scrollLock.release();
|
|
42
|
+
withPointer(event, controller.end);
|
|
43
|
+
}} onResponderTerminate={() => {
|
|
44
|
+
scrollLock.release();
|
|
36
45
|
setSpaceKey(false);
|
|
37
46
|
pointerQueue.cancel();
|
|
38
47
|
controller.cancel();
|
|
39
|
-
}} onStartShouldSetResponder={() => enabled}>
|
|
48
|
+
}} onResponderTerminationRequest={() => false} onStartShouldSetResponder={() => enabled}>
|
|
40
49
|
<GridInteractionsKeyboardProxy enabled={enabled} onKeyDown={(key, keyPointer) => {
|
|
41
50
|
return controller.keyDown(key, keyPointer);
|
|
42
51
|
}} onSpaceKeyChange={setSpaceKey}>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridInteractions.js","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMpC,OAAO,EAAE,gCAAgC,EAAE,MAAM,oDAAoD,CAAC;AACtG,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"GridInteractions.js","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractions.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { View } from 'react-native';\n\nimport type {\n GridInteractionsController,\n GridInteractionsProps,\n} from '../../../../types/grid-interactions';\nimport { createGridInteractionsController } from '../../application/createGridInteractionsController';\nimport { createGridInteractionsPointerQueue } from './createGridInteractionsPointerQueue';\nimport { GridInteractionsKeyboardProxy } from './GridInteractionsKeyboardProxy';\nimport { resolveGridInteractionPointer } from './resolveGridInteractionPointer';\nimport { useGridInteractionScrollLock } from './useGridInteractionScrollLock';\n\n/*** Adapts native responder and keyboard events to the controlled grid interaction boundary. */\nexport function GridInteractions({\n children,\n interactionPolicy,\n resizeHandle,\n testID,\n ...props\n}: GridInteractionsProps) {\n const controllerProps = React.useMemo(\n () => ({ ...props, interactionPolicy }),\n [interactionPolicy, props],\n );\n const [controller] = React.useState<GridInteractionsController>(() =>\n createGridInteractionsController(controllerProps),\n );\n const surfaceRef = React.useRef<View>(null);\n const spaceKeyRef = React.useRef(false);\n const [pointerQueue] = React.useState(() => createGridInteractionsPointerQueue());\n const scrollLock = useGridInteractionScrollLock();\n React.useLayoutEffect(() => controller.update(controllerProps), [controller, controllerProps]);\n React.useLayoutEffect(() => {\n pointerQueue.activate();\n return () => {\n spaceKeyRef.current = false;\n pointerQueue.dispose();\n controller.cancel();\n };\n }, [controller, pointerQueue]);\n const setSpaceKey = React.useCallback((spaceKey: boolean) => {\n spaceKeyRef.current = spaceKey;\n }, []);\n const withPointer = (\n event: Parameters<typeof resolveGridInteractionPointer>[0],\n handlePointer: (pointer: ReturnType<typeof resolveGridInteractionPointer>) => void,\n ) => {\n const surface = surfaceRef.current;\n if (!surface) return;\n const eventSnapshot = { nativeEvent: { ...event.nativeEvent } };\n const modifierSnapshot = { spaceKey: spaceKeyRef.current };\n pointerQueue.enqueue(surface, (origin) =>\n handlePointer(resolveGridInteractionPointer(eventSnapshot, origin, modifierSnapshot)),\n );\n };\n const enabled = interactionPolicy !== 'passive';\n\n return (\n <View\n accessible\n accessibilityLabel=\"Grid interaction surface\"\n ref={surfaceRef}\n testID={testID}\n onResponderGrant={(event) => {\n scrollLock.acquire();\n withPointer(event, (pointer) => controller.begin(pointer, resizeHandle));\n }}\n onResponderMove={(event) => withPointer(event, controller.move)}\n onResponderRelease={(event) => {\n scrollLock.release();\n withPointer(event, controller.end);\n }}\n onResponderTerminate={() => {\n scrollLock.release();\n setSpaceKey(false);\n pointerQueue.cancel();\n controller.cancel();\n }}\n onResponderTerminationRequest={() => false}\n onStartShouldSetResponder={() => enabled}\n >\n <GridInteractionsKeyboardProxy\n enabled={enabled}\n onKeyDown={(key, keyPointer) => {\n return controller.keyDown(key, keyPointer);\n }}\n onSpaceKeyChange={setSpaceKey}\n >\n {children}\n </GridInteractionsKeyboardProxy>\n </View>\n );\n}\n"]}
|
package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridInteractionsKeyboardProxy.web.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAElF,oGAAoG;AACpG,wBAAgB,6BAA6B,CAAC,EAC5C,QAAQ,EACR,OAAO,EACP,SAAS,EACT,gBAAgB,GACjB,EAAE,kCAAkC,
|
|
1
|
+
{"version":3,"file":"GridInteractionsKeyboardProxy.web.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAElF,oGAAoG;AACpG,wBAAgB,6BAA6B,CAAC,EAC5C,QAAQ,EACR,OAAO,EACP,SAAS,EACT,gBAAgB,GACjB,EAAE,kCAAkC,qBAoCpC;AAUD,UAAU,kCAAkC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC;IAC9E,QAAQ,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACxD"}
|
package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js
CHANGED
|
@@ -6,7 +6,7 @@ export function GridInteractionsKeyboardProxy({ children, enabled, onKeyDown, on
|
|
|
6
6
|
onSpaceKeyChange(false);
|
|
7
7
|
}, [enabled, onSpaceKeyChange]);
|
|
8
8
|
React.useEffect(() => () => onSpaceKeyChange(false), [onSpaceKeyChange]);
|
|
9
|
-
return (<div aria-label="Grid interaction keyboard controls" onBlur={() => onSpaceKeyChange(false)} onKeyDown={(event) => {
|
|
9
|
+
return (<div aria-label="Grid interaction keyboard controls" role="group" onBlur={() => onSpaceKeyChange(false)} onKeyDown={(event) => {
|
|
10
10
|
if (!enabled)
|
|
11
11
|
return;
|
|
12
12
|
if (isSpaceKey(event))
|
|
@@ -24,10 +24,17 @@ export function GridInteractionsKeyboardProxy({ children, enabled, onKeyDown, on
|
|
|
24
24
|
}} onKeyUp={(event) => {
|
|
25
25
|
if (isSpaceKey(event))
|
|
26
26
|
onSpaceKeyChange(false);
|
|
27
|
-
}} style={
|
|
27
|
+
}} style={keyboardBoundaryStyle} tabIndex={enabled ? 0 : -1}>
|
|
28
28
|
{children}
|
|
29
29
|
</div>);
|
|
30
30
|
}
|
|
31
|
+
const keyboardBoundaryStyle = {
|
|
32
|
+
alignSelf: 'stretch',
|
|
33
|
+
display: 'flex',
|
|
34
|
+
flex: 1,
|
|
35
|
+
minHeight: 0,
|
|
36
|
+
minWidth: 0,
|
|
37
|
+
};
|
|
31
38
|
/*** Determines whether a web keyboard event represents the Space modifier. */
|
|
32
39
|
function isSpaceKey(event) {
|
|
33
40
|
return event.code === 'Space' || event.key === ' ';
|
package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridInteractionsKeyboardProxy.web.js","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,oGAAoG;AACpG,MAAM,UAAU,6BAA6B,CAAC,EAC5C,QAAQ,EACR,OAAO,EACP,SAAS,EACT,gBAAgB,GACmB;IACnC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,OAAO;YAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAChC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEzE,OAAO,CACL,CAAC,GAAG,CACF,UAAU,CAAC,oCAAoC,CAC/C,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CACtC,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC9C,IACE,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE;gBACnB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,CAAC;aACL,CAAC,EACF,CAAC;gBACD,KAAK,CAAC,cAAc,EAAE,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CACF,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CACF,KAAK,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"GridInteractionsKeyboardProxy.web.js","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,oGAAoG;AACpG,MAAM,UAAU,6BAA6B,CAAC,EAC5C,QAAQ,EACR,OAAO,EACP,SAAS,EACT,gBAAgB,GACmB;IACnC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,OAAO;YAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAChC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEzE,OAAO,CACL,CAAC,GAAG,CACF,UAAU,CAAC,oCAAoC,CAC/C,IAAI,CAAC,OAAO,CACZ,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CACtC,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC9C,IACE,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE;gBACnB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,CAAC;aACL,CAAC,EACF,CAAC;gBACD,KAAK,CAAC,cAAc,EAAE,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CACF,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CACF,KAAK,CAAC,CAAC,qBAAqB,CAAC,CAC7B,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAE3B;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC;AAED,MAAM,qBAAqB,GAAG;IAC5B,SAAS,EAAE,SAAS;IACpB,OAAO,EAAE,MAAM;IACf,IAAI,EAAE,CAAC;IACP,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,CAAC;CACH,CAAC;AASX,8EAA8E;AAC9E,SAAS,UAAU,CAAC,KAA0C;IAC5D,OAAO,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC;AACrD,CAAC","sourcesContent":["import React from 'react';\n\nimport type { GridInteractionPointer } from '../../../../types/grid-interactions';\n\n/*** Adapts web keyboard movement and resize commands without changing native responder behavior. */\nexport function GridInteractionsKeyboardProxy({\n children,\n enabled,\n onKeyDown,\n onSpaceKeyChange,\n}: GridInteractionsKeyboardProxyProps) {\n React.useEffect(() => {\n if (!enabled) onSpaceKeyChange(false);\n }, [enabled, onSpaceKeyChange]);\n React.useEffect(() => () => onSpaceKeyChange(false), [onSpaceKeyChange]);\n\n return (\n <div\n aria-label=\"Grid interaction keyboard controls\"\n role=\"group\"\n onBlur={() => onSpaceKeyChange(false)}\n onKeyDown={(event) => {\n if (!enabled) return;\n if (isSpaceKey(event)) onSpaceKeyChange(true);\n if (\n onKeyDown(event.key, {\n altKey: event.altKey,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n x: 0,\n y: 0,\n })\n ) {\n event.preventDefault();\n }\n }}\n onKeyUp={(event) => {\n if (isSpaceKey(event)) onSpaceKeyChange(false);\n }}\n style={keyboardBoundaryStyle}\n tabIndex={enabled ? 0 : -1}\n >\n {children}\n </div>\n );\n}\n\nconst keyboardBoundaryStyle = {\n alignSelf: 'stretch',\n display: 'flex',\n flex: 1,\n minHeight: 0,\n minWidth: 0,\n} as const;\n\ninterface GridInteractionsKeyboardProxyProps {\n readonly children: React.ReactNode;\n readonly enabled: boolean;\n readonly onKeyDown: (key: string, pointer: GridInteractionPointer) => boolean;\n readonly onSpaceKeyChange: (spaceKey: boolean) => void;\n}\n\n/*** Determines whether a web keyboard event represents the Space modifier. */\nfunction isSpaceKey(event: React.KeyboardEvent<HTMLDivElement>): boolean {\n return event.code === 'Space' || event.key === ' ';\n}\n"]}
|
package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridInteractionScrollLock.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridInteractionScrollLock.js","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC","sourcesContent":["export { useGridInteractionScrollLock } from './useGridInteractionScrollLock.native';\n"]}
|
package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GridInteractionScrollLock } from '../../../../types/grid-interactions';
|
|
2
|
+
/*** Keeps ancestor ZORA scrolling suspended while one native responder gesture owns the surface. */
|
|
3
|
+
export declare function useGridInteractionScrollLock(): GridInteractionScrollLock;
|
|
4
|
+
//# sourceMappingURL=useGridInteractionScrollLock.native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridInteractionScrollLock.native.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAIrF,oGAAoG;AACpG,wBAAgB,4BAA4B,IAAI,yBAAyB,CASxE"}
|
package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useScrollGestureLock } from '../../../layout/public';
|
|
3
|
+
import { createGridInteractionScrollLock } from '../../application/createGridInteractionScrollLock';
|
|
4
|
+
/*** Keeps ancestor ZORA scrolling suspended while one native responder gesture owns the surface. */
|
|
5
|
+
export function useGridInteractionScrollLock() {
|
|
6
|
+
const scrollLock = useScrollGestureLock();
|
|
7
|
+
const gestureLock = React.useMemo(() => createGridInteractionScrollLock(scrollLock), [scrollLock]);
|
|
8
|
+
React.useEffect(() => gestureLock.release, [gestureLock]);
|
|
9
|
+
return gestureLock;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=useGridInteractionScrollLock.native.js.map
|
package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridInteractionScrollLock.native.js","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,mDAAmD,CAAC;AAEpG,oGAAoG;AACpG,MAAM,UAAU,4BAA4B;IAC1C,MAAM,UAAU,GAAG,oBAAoB,EAAE,CAAC;IAC1C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAC/B,GAAG,EAAE,CAAC,+BAA+B,CAAC,UAAU,CAAC,EACjD,CAAC,UAAU,CAAC,CACb,CAAC;IACF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAE1D,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import React from 'react';\n\nimport type { GridInteractionScrollLock } from '../../../../types/grid-interactions';\nimport { useScrollGestureLock } from '../../../layout/public';\nimport { createGridInteractionScrollLock } from '../../application/createGridInteractionScrollLock';\n\n/*** Keeps ancestor ZORA scrolling suspended while one native responder gesture owns the surface. */\nexport function useGridInteractionScrollLock(): GridInteractionScrollLock {\n const scrollLock = useScrollGestureLock();\n const gestureLock = React.useMemo(\n () => createGridInteractionScrollLock(scrollLock),\n [scrollLock],\n );\n React.useEffect(() => gestureLock.release, [gestureLock]);\n\n return gestureLock;\n}\n"]}
|
package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GridInteractionScrollLock } from '../../../../types/grid-interactions';
|
|
2
|
+
/*** Leaves browser scrolling to the RNW responder system, which already honors termination requests. */
|
|
3
|
+
export declare function useGridInteractionScrollLock(): GridInteractionScrollLock;
|
|
4
|
+
//# sourceMappingURL=useGridInteractionScrollLock.web.d.ts.map
|
package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridInteractionScrollLock.web.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAOrF,wGAAwG;AACxG,wBAAgB,4BAA4B,IAAI,yBAAyB,CAExE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const webScrollLock = {
|
|
2
|
+
acquire: () => undefined,
|
|
3
|
+
release: () => undefined,
|
|
4
|
+
};
|
|
5
|
+
/*** Leaves browser scrolling to the RNW responder system, which already honors termination requests. */
|
|
6
|
+
export function useGridInteractionScrollLock() {
|
|
7
|
+
return webScrollLock;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=useGridInteractionScrollLock.web.js.map
|
package/dist/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridInteractionScrollLock.web.js","sourceRoot":"","sources":["../../../../../src/features/grid-interactions/adapters/inbound/useGridInteractionScrollLock.web.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAA8B;IAC/C,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;IACxB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;CACzB,CAAC;AAEF,wGAAwG;AACxG,MAAM,UAAU,4BAA4B;IAC1C,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import type { GridInteractionScrollLock } from '../../../../types/grid-interactions';\n\nconst webScrollLock: GridInteractionScrollLock = {\n acquire: () => undefined,\n release: () => undefined,\n};\n\n/*** Leaves browser scrolling to the RNW responder system, which already honors termination requests. */\nexport function useGridInteractionScrollLock(): GridInteractionScrollLock {\n return webScrollLock;\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { GridInteractionScrollLock } from '../../../types/grid-interactions';
|
|
2
|
+
import type { ScrollGestureLock } from '../../../types/layout';
|
|
3
|
+
/*** Holds at most one ancestor scroll lock for the active responder gesture of an interaction surface. */
|
|
4
|
+
export declare function createGridInteractionScrollLock(scrollLock: ScrollGestureLock): GridInteractionScrollLock;
|
|
5
|
+
//# sourceMappingURL=createGridInteractionScrollLock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGridInteractionScrollLock.d.ts","sourceRoot":"","sources":["../../../../src/features/grid-interactions/application/createGridInteractionScrollLock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,0GAA0G;AAC1G,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,iBAAiB,GAC5B,yBAAyB,CAW3B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*** Holds at most one ancestor scroll lock for the active responder gesture of an interaction surface. */
|
|
2
|
+
export function createGridInteractionScrollLock(scrollLock) {
|
|
3
|
+
let releaseScrollLock;
|
|
4
|
+
return {
|
|
5
|
+
acquire: () => {
|
|
6
|
+
releaseScrollLock ??= scrollLock.acquire();
|
|
7
|
+
},
|
|
8
|
+
release: () => {
|
|
9
|
+
releaseScrollLock?.();
|
|
10
|
+
releaseScrollLock = undefined;
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=createGridInteractionScrollLock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGridInteractionScrollLock.js","sourceRoot":"","sources":["../../../../src/features/grid-interactions/application/createGridInteractionScrollLock.ts"],"names":[],"mappings":"AAGA,0GAA0G;AAC1G,MAAM,UAAU,+BAA+B,CAC7C,UAA6B;IAE7B,IAAI,iBAA2C,CAAC;IAChD,OAAO;QACL,OAAO,EAAE,GAAG,EAAE;YACZ,iBAAiB,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QAC7C,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,iBAAiB,EAAE,EAAE,CAAC;YACtB,iBAAiB,GAAG,SAAS,CAAC;QAChC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { GridInteractionScrollLock } from '../../../types/grid-interactions';\nimport type { ScrollGestureLock } from '../../../types/layout';\n\n/*** Holds at most one ancestor scroll lock for the active responder gesture of an interaction surface. */\nexport function createGridInteractionScrollLock(\n scrollLock: ScrollGestureLock,\n): GridInteractionScrollLock {\n let releaseScrollLock: (() => void) | undefined;\n return {\n acquire: () => {\n releaseScrollLock ??= scrollLock.acquire();\n },\n release: () => {\n releaseScrollLock?.();\n releaseScrollLock = undefined;\n },\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridView.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"GridView.d.ts","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,OAAO,KAAK,EAAkC,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAiBjG,8GAA8G;AAC9G,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,YAAY,EACZ,aAAa,EACb,KAAK,EACL,MAAM,EACN,QAAQ,EAAE,kBAAkB,EAC5B,eAAe,EACf,mBAAmB,EACnB,UAAU,EACV,IAAQ,EACR,cAAoB,EACpB,aAAa,EACb,mBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,MAAM,GACP,EAAE,aAAa,qBAiYf"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { constrainViewport, getVisibleGridItems, panViewport, revealWorldRect, worldToViewport, zoomViewportAt, } from '@ankhorage/grid-view';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Pressable as NativePressable, ScrollView as NativeScrollView, Text as NativeText, View as NativeView, } from 'react-native';
|
|
4
|
+
import { createGridScrollSync } from '../../application/createGridScrollSync';
|
|
4
5
|
/*** Renders a controlled or uncontrolled, virtualized 2D world through the canonical grid viewport engine. */
|
|
5
6
|
export function GridView({ items, contentWidth, contentHeight, width, height, viewport: controlledViewport, defaultViewport, viewportConstraints, zoomLimits, zoom = 1, overscanPixels = 160, focusedItemId, revealPaddingPixels = 8, interactionPolicy, onViewportChange, onVisibleItemIdsChange, renderItem, testID, }) {
|
|
6
7
|
const [uncontrolledViewport, setUncontrolledViewport] = React.useState(() => createInitialViewport(width, height, zoom, defaultViewport));
|
|
7
8
|
const horizontalScrollRef = React.useRef(null);
|
|
8
9
|
const verticalScrollRef = React.useRef(null);
|
|
9
10
|
const gridRef = React.useRef(null);
|
|
10
|
-
const
|
|
11
|
+
const panRef = React.useRef(() => undefined);
|
|
12
|
+
const scrollSyncRef = React.useRef(undefined);
|
|
11
13
|
const pinchGestureRef = React.useRef(undefined);
|
|
12
14
|
const pinchMeasurementRef = React.useRef(0);
|
|
13
15
|
const pinchSessionRef = React.useRef(0);
|
|
@@ -50,6 +52,32 @@ export function GridView({ items, contentWidth, contentHeight, width, height, vi
|
|
|
50
52
|
React.useEffect(() => {
|
|
51
53
|
publishRef.current = publish;
|
|
52
54
|
}, [publish]);
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
panRef.current = pan;
|
|
57
|
+
});
|
|
58
|
+
// Declared before the viewport-sync effect so the arbiter exists when that effect runs.
|
|
59
|
+
React.useEffect(() => {
|
|
60
|
+
const scrollSync = createGridScrollSync({
|
|
61
|
+
onProgrammaticScroll: (axis, displacement) => panRef.current(axis === 'x' ? { x: -displacement, y: 0 } : { x: 0, y: -displacement }),
|
|
62
|
+
onUserScroll: (axis, displacement) => panRef.current(axis === 'x' ? { x: -displacement, y: 0 } : { x: 0, y: -displacement }),
|
|
63
|
+
scrollTo: (axis, offset, animated) => {
|
|
64
|
+
if (axis === 'x')
|
|
65
|
+
horizontalScrollRef.current?.scrollTo({ animated, x: offset });
|
|
66
|
+
else
|
|
67
|
+
verticalScrollRef.current?.scrollTo({ animated, y: offset });
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
scrollSyncRef.current = scrollSync;
|
|
71
|
+
return () => {
|
|
72
|
+
scrollSync.dispose();
|
|
73
|
+
scrollSyncRef.current = undefined;
|
|
74
|
+
};
|
|
75
|
+
}, []);
|
|
76
|
+
/** Routes native scroll events to the arbiter unless a pinch owns the gesture. */
|
|
77
|
+
const handleNativeScroll = (axis, offset) => {
|
|
78
|
+
if (!pinchGestureRef.current)
|
|
79
|
+
scrollSyncRef.current?.scrolled(axis, offset);
|
|
80
|
+
};
|
|
53
81
|
const refreshViewportOrigin = React.useCallback(() => {
|
|
54
82
|
gridRef.current?.measureInWindow((x, y) => {
|
|
55
83
|
viewportOriginRef.current = { x, y };
|
|
@@ -90,13 +118,11 @@ export function GridView({ items, contentWidth, contentHeight, width, height, vi
|
|
|
90
118
|
x: position.horizontal.position,
|
|
91
119
|
y: position.vertical.position,
|
|
92
120
|
};
|
|
93
|
-
if (
|
|
121
|
+
if (scrollSyncRef.current?.isCurrent(nextPosition))
|
|
94
122
|
return;
|
|
95
|
-
scrollPositionRef.current = nextPosition;
|
|
96
123
|
const animated = focusRevealViewportRef.current !== undefined &&
|
|
97
124
|
areViewportsEqual(viewport, focusRevealViewportRef.current);
|
|
98
|
-
|
|
99
|
-
verticalScrollRef.current?.scrollTo({ animated, y: nextPosition.y });
|
|
125
|
+
scrollSyncRef.current?.request(nextPosition, animated);
|
|
100
126
|
if (animated)
|
|
101
127
|
focusRevealViewportRef.current = undefined;
|
|
102
128
|
}, [constraints, viewport]);
|
|
@@ -151,9 +177,7 @@ export function GridView({ items, contentWidth, contentHeight, width, height, vi
|
|
|
151
177
|
x: nextMapping.horizontal.position,
|
|
152
178
|
y: nextMapping.vertical.position,
|
|
153
179
|
};
|
|
154
|
-
|
|
155
|
-
horizontalScrollRef.current?.scrollTo({ animated: false, x: nextPosition.x });
|
|
156
|
-
verticalScrollRef.current?.scrollTo({ animated: false, y: nextPosition.y });
|
|
180
|
+
scrollSyncRef.current?.request(nextPosition, false);
|
|
157
181
|
};
|
|
158
182
|
return (<NativeView ref={gridRef} accessibilityLabel="Interactive grid viewport" onLayout={refreshViewportOrigin} onTouchEnd={() => {
|
|
159
183
|
const wasPinching = pinchGestureRef.current !== undefined;
|
|
@@ -190,24 +214,8 @@ export function GridView({ items, contentWidth, contentHeight, width, height, vi
|
|
|
190
214
|
setIsPinching(pinch !== undefined);
|
|
191
215
|
});
|
|
192
216
|
}} style={{ height, overflow: 'hidden', width }} testID={testID}>
|
|
193
|
-
<NativeScrollView ref={horizontalScrollRef} testID={testID ? `${testID}-horizontal-scroll` : undefined} horizontal scrollEnabled={interactive && !isPinching} scrollEventThrottle={16} showsHorizontalScrollIndicator style={{ height, width }} onScroll={(event) => {
|
|
194
|
-
|
|
195
|
-
return;
|
|
196
|
-
const { x } = event.nativeEvent.contentOffset;
|
|
197
|
-
const displacement = x - scrollPositionRef.current.x;
|
|
198
|
-
scrollPositionRef.current = { ...scrollPositionRef.current, x };
|
|
199
|
-
if (displacement !== 0)
|
|
200
|
-
pan({ x: -displacement, y: 0 });
|
|
201
|
-
}}>
|
|
202
|
-
<NativeScrollView ref={verticalScrollRef} testID={testID ? `${testID}-vertical-scroll` : undefined} scrollEnabled={interactive && !isPinching} scrollEventThrottle={16} showsVerticalScrollIndicator style={{ height, width: scrollMapping.horizontal.contentSize }} onScroll={(event) => {
|
|
203
|
-
if (pinchGestureRef.current)
|
|
204
|
-
return;
|
|
205
|
-
const { y } = event.nativeEvent.contentOffset;
|
|
206
|
-
const displacement = y - scrollPositionRef.current.y;
|
|
207
|
-
scrollPositionRef.current = { ...scrollPositionRef.current, y };
|
|
208
|
-
if (displacement !== 0)
|
|
209
|
-
pan({ x: 0, y: -displacement });
|
|
210
|
-
}}>
|
|
217
|
+
<NativeScrollView ref={horizontalScrollRef} testID={testID ? `${testID}-horizontal-scroll` : undefined} horizontal scrollEnabled={interactive && !isPinching} scrollEventThrottle={16} showsHorizontalScrollIndicator style={{ height, width }} onMomentumScrollEnd={(event) => scrollSyncRef.current?.scrollEnded('x', event.nativeEvent.contentOffset.x)} onScroll={(event) => handleNativeScroll('x', event.nativeEvent.contentOffset.x)} onScrollBeginDrag={(event) => scrollSyncRef.current?.dragBegan('x', event.nativeEvent.contentOffset.x)}>
|
|
218
|
+
<NativeScrollView ref={verticalScrollRef} testID={testID ? `${testID}-vertical-scroll` : undefined} scrollEnabled={interactive && !isPinching} scrollEventThrottle={16} showsVerticalScrollIndicator style={{ height, width: scrollMapping.horizontal.contentSize }} onMomentumScrollEnd={(event) => scrollSyncRef.current?.scrollEnded('y', event.nativeEvent.contentOffset.y)} onScroll={(event) => handleNativeScroll('y', event.nativeEvent.contentOffset.y)} onScrollBeginDrag={(event) => scrollSyncRef.current?.dragBegan('y', event.nativeEvent.contentOffset.y)}>
|
|
211
219
|
<NativeView style={{
|
|
212
220
|
height: scrollMapping.vertical.contentSize,
|
|
213
221
|
width: scrollMapping.horizontal.contentSize,
|
|
@@ -306,10 +314,6 @@ function areViewportsEqual(left, right) {
|
|
|
306
314
|
left.pixelsPerUnitX === right.pixelsPerUnitX &&
|
|
307
315
|
left.pixelsPerUnitY === right.pixelsPerUnitY);
|
|
308
316
|
}
|
|
309
|
-
/*** Avoids requesting native scrolling again when the physical position is already current. */
|
|
310
|
-
function areScrollPositionsEqual(left, right) {
|
|
311
|
-
return left.x === right.x && left.y === right.y;
|
|
312
|
-
}
|
|
313
317
|
/*** Skips a rejected controlled focus proposal until its focus or incoming viewport changes. */
|
|
314
318
|
function isRepeatedControlledFocusRevealProposal({ controlled, focusedItemId, previous, sourceViewport, viewport, }) {
|
|
315
319
|
return (controlled &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridView.js","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n constrainViewport,\n getVisibleGridItems,\n type GridPoint,\n type GridViewport,\n type GridViewportConstraints,\n panViewport,\n revealWorldRect,\n worldToViewport,\n zoomViewportAt,\n} from '@ankhorage/grid-view';\nimport React from 'react';\nimport {\n Pressable as NativePressable,\n ScrollView as NativeScrollView,\n Text as NativeText,\n View as NativeView,\n} from 'react-native';\n\nimport type { GridViewProps } from '../../../../types/grid-view';\n\ntype ScrollPosition = Readonly<{ x: number; y: number }>;\ntype PinchGesture = Readonly<{ distance: number; focalPoint: GridPoint }>;\ntype ScrollAxisMapping = Readonly<{ contentSize: number; origin: number; position: number }>;\ntype ScrollMapping = Readonly<{\n horizontal: ScrollAxisMapping;\n vertical: ScrollAxisMapping;\n}>;\ntype ViewportOrigin = Readonly<{ x: number; y: number }>;\ntype FocusRevealProposal = Readonly<{\n focusedItemId: string;\n sourceViewport: GridViewport;\n viewport: GridViewport;\n}>;\ntype PinchTouch = Readonly<{ pageX: number; pageY: number }>;\n\n/*** Renders a controlled or uncontrolled, virtualized 2D world through the canonical grid viewport engine. */\nexport function GridView({\n items,\n contentWidth,\n contentHeight,\n width,\n height,\n viewport: controlledViewport,\n defaultViewport,\n viewportConstraints,\n zoomLimits,\n zoom = 1,\n overscanPixels = 160,\n focusedItemId,\n revealPaddingPixels = 8,\n interactionPolicy,\n onViewportChange,\n onVisibleItemIdsChange,\n renderItem,\n testID,\n}: GridViewProps) {\n const [uncontrolledViewport, setUncontrolledViewport] = React.useState(() =>\n createInitialViewport(width, height, zoom, defaultViewport),\n );\n const horizontalScrollRef = React.useRef<NativeScrollView>(null);\n const verticalScrollRef = React.useRef<NativeScrollView>(null);\n const gridRef = React.useRef<React.ComponentRef<typeof NativeView>>(null);\n const scrollPositionRef = React.useRef<ScrollPosition>({ x: 0, y: 0 });\n const pinchGestureRef = React.useRef<PinchGesture | undefined>(undefined);\n const pinchMeasurementRef = React.useRef(0);\n const pinchSessionRef = React.useRef(0);\n const viewportOriginRef = React.useRef<ViewportOrigin>({ x: 0, y: 0 });\n const focusRevealProposalRef = React.useRef<FocusRevealProposal | undefined>(undefined);\n const focusRevealViewportRef = React.useRef<GridViewport | undefined>(undefined);\n const [isPinching, setIsPinching] = React.useState(false);\n const constraints = React.useMemo(\n () => viewportConstraints ?? createContentConstraints(contentWidth, contentHeight),\n [contentHeight, contentWidth, viewportConstraints],\n );\n const sourceViewport = controlledViewport ?? uncontrolledViewport;\n const viewport = React.useMemo(\n () => constrainViewport({ ...sourceViewport, height, width }, constraints),\n [constraints, height, sourceViewport, width],\n );\n const viewportRef = React.useRef(viewport);\n const visibleItems = React.useMemo(\n () => getVisibleGridItems(items, viewport, overscanPixels),\n [items, overscanPixels, viewport],\n );\n const viewportVisibleIds = React.useMemo(\n () => getVisibleGridItems(visibleItems, viewport).map((item) => item.id),\n [viewport, visibleItems],\n );\n const focusedItem = items.find((item) => item.id === focusedItemId);\n const focusedItemHeight = focusedItem?.height;\n const focusedItemIdForReveal = focusedItem?.id;\n const focusedItemWidth = focusedItem?.width;\n const focusedItemX = focusedItem?.x;\n const focusedItemY = focusedItem?.y;\n const previousVisibleIdsRef = React.useRef<readonly string[]>([]);\n const uncontrolled = controlledViewport === undefined;\n const interactive = interactionPolicy !== 'passive';\n\n const publish = React.useCallback(\n (nextViewport: GridViewport) => {\n if (areViewportsEqual(viewportRef.current, nextViewport)) return;\n viewportRef.current = nextViewport;\n if (uncontrolled) setUncontrolledViewport(nextViewport);\n onViewportChange?.(nextViewport);\n },\n [onViewportChange, uncontrolled],\n );\n const publishRef = React.useRef(publish);\n const pan = (displacement: GridPoint) =>\n publish(panViewport(viewportRef.current, displacement, constraints));\n const zoomAt = (focalPoint: GridPoint, factor: number) =>\n publish(\n zoomViewportAt(\n viewportRef.current,\n focalPoint,\n {\n pixelsPerUnitX: viewportRef.current.pixelsPerUnitX * factor,\n pixelsPerUnitY: viewportRef.current.pixelsPerUnitY * factor,\n },\n zoomLimits,\n constraints,\n ),\n );\n\n React.useEffect(() => {\n viewportRef.current = viewport;\n }, [viewport]);\n\n React.useEffect(() => {\n publishRef.current = publish;\n }, [publish]);\n\n const refreshViewportOrigin = React.useCallback(() => {\n gridRef.current?.measureInWindow((x, y) => {\n viewportOriginRef.current = { x, y };\n });\n }, []);\n\n const measurePinchGesture = React.useCallback(\n (\n touches: readonly PinchTouch[],\n session: number,\n onMeasured: (pinch: PinchGesture | undefined) => void,\n ) => {\n const measurement = pinchMeasurementRef.current + 1;\n pinchMeasurementRef.current = measurement;\n gridRef.current?.measureInWindow((x, y) => {\n if (measurement !== pinchMeasurementRef.current || session !== pinchSessionRef.current) {\n return;\n }\n viewportOriginRef.current = { x, y };\n onMeasured(getPinchGesture(touches, width, height, { x, y }));\n });\n },\n [height, width],\n );\n\n React.useLayoutEffect(() => {\n refreshViewportOrigin();\n }, [height, refreshViewportOrigin, width]);\n\n React.useEffect(\n () => () => {\n pinchMeasurementRef.current += 1;\n pinchSessionRef.current += 1;\n },\n [],\n );\n\n React.useEffect(() => {\n if (!onVisibleItemIdsChange) return;\n const previous = previousVisibleIdsRef.current;\n if (\n previous.length === viewportVisibleIds.length &&\n previous.every((id, index) => id === viewportVisibleIds.at(index))\n ) {\n return;\n }\n previousVisibleIdsRef.current = viewportVisibleIds;\n onVisibleItemIdsChange(viewportVisibleIds);\n }, [onVisibleItemIdsChange, viewportVisibleIds]);\n\n React.useEffect(() => {\n const position = createScrollMapping(viewport, constraints);\n const nextPosition = {\n x: position.horizontal.position,\n y: position.vertical.position,\n };\n if (areScrollPositionsEqual(scrollPositionRef.current, nextPosition)) return;\n scrollPositionRef.current = nextPosition;\n const animated =\n focusRevealViewportRef.current !== undefined &&\n areViewportsEqual(viewport, focusRevealViewportRef.current);\n horizontalScrollRef.current?.scrollTo({ animated, x: nextPosition.x });\n verticalScrollRef.current?.scrollTo({ animated, y: nextPosition.y });\n if (animated) focusRevealViewportRef.current = undefined;\n }, [constraints, viewport]);\n\n React.useEffect(() => {\n if (\n focusedItemHeight === undefined ||\n focusedItemIdForReveal === undefined ||\n focusedItemWidth === undefined ||\n focusedItemX === undefined ||\n focusedItemY === undefined\n ) {\n focusRevealProposalRef.current = undefined;\n return;\n }\n const sourceViewport = viewportRef.current;\n const revealed = revealWorldRect(\n sourceViewport,\n {\n height: focusedItemHeight,\n width: focusedItemWidth,\n x: focusedItemX,\n y: focusedItemY,\n },\n revealPaddingPixels,\n constraints,\n );\n if (\n isRepeatedControlledFocusRevealProposal({\n controlled: !uncontrolled,\n focusedItemId: focusedItemIdForReveal,\n previous: focusRevealProposalRef.current,\n sourceViewport,\n viewport: revealed,\n })\n ) {\n return;\n }\n focusRevealProposalRef.current = {\n focusedItemId: focusedItemIdForReveal,\n sourceViewport,\n viewport: revealed,\n };\n focusRevealViewportRef.current = areViewportsEqual(sourceViewport, revealed)\n ? undefined\n : revealed;\n publishRef.current(revealed);\n }, [\n constraints,\n focusedItemHeight,\n focusedItemIdForReveal,\n focusedItemWidth,\n focusedItemX,\n focusedItemY,\n revealPaddingPixels,\n uncontrolled,\n ]);\n\n const scrollMapping = createScrollMapping(viewport, constraints);\n\n const syncScrollPosition = () => {\n const nextMapping = createScrollMapping(viewportRef.current, constraints);\n const nextPosition = {\n x: nextMapping.horizontal.position,\n y: nextMapping.vertical.position,\n };\n scrollPositionRef.current = nextPosition;\n horizontalScrollRef.current?.scrollTo({ animated: false, x: nextPosition.x });\n verticalScrollRef.current?.scrollTo({ animated: false, y: nextPosition.y });\n };\n\n return (\n <NativeView\n ref={gridRef}\n accessibilityLabel=\"Interactive grid viewport\"\n onLayout={refreshViewportOrigin}\n onTouchEnd={() => {\n const wasPinching = pinchGestureRef.current !== undefined;\n pinchMeasurementRef.current += 1;\n pinchSessionRef.current += 1;\n pinchGestureRef.current = undefined;\n setIsPinching(false);\n if (wasPinching) syncScrollPosition();\n }}\n onTouchCancel={() => {\n const wasPinching = pinchGestureRef.current !== undefined;\n pinchMeasurementRef.current += 1;\n pinchSessionRef.current += 1;\n pinchGestureRef.current = undefined;\n setIsPinching(false);\n if (wasPinching) syncScrollPosition();\n }}\n onTouchMove={(event) => {\n if (!interactive) return;\n measurePinchGesture([...event.nativeEvent.touches], pinchSessionRef.current, (pinch) => {\n const previous = pinchGestureRef.current;\n pinchGestureRef.current = pinch;\n setIsPinching(pinch !== undefined);\n if (!pinch || !previous) return;\n zoomAt(pinch.focalPoint, pinch.distance / previous.distance);\n });\n }}\n onTouchStart={(event) => {\n const session = pinchSessionRef.current + 1;\n pinchSessionRef.current = session;\n measurePinchGesture([...event.nativeEvent.touches], session, (pinch) => {\n pinchGestureRef.current = pinch;\n setIsPinching(pinch !== undefined);\n });\n }}\n style={{ height, overflow: 'hidden', width }}\n testID={testID}\n >\n <NativeScrollView\n ref={horizontalScrollRef}\n testID={testID ? `${testID}-horizontal-scroll` : undefined}\n horizontal\n scrollEnabled={interactive && !isPinching}\n scrollEventThrottle={16}\n showsHorizontalScrollIndicator\n style={{ height, width }}\n onScroll={(event) => {\n if (pinchGestureRef.current) return;\n const { x } = event.nativeEvent.contentOffset;\n const displacement = x - scrollPositionRef.current.x;\n scrollPositionRef.current = { ...scrollPositionRef.current, x };\n if (displacement !== 0) pan({ x: -displacement, y: 0 });\n }}\n >\n <NativeScrollView\n ref={verticalScrollRef}\n testID={testID ? `${testID}-vertical-scroll` : undefined}\n scrollEnabled={interactive && !isPinching}\n scrollEventThrottle={16}\n showsVerticalScrollIndicator\n style={{ height, width: scrollMapping.horizontal.contentSize }}\n onScroll={(event) => {\n if (pinchGestureRef.current) return;\n const { y } = event.nativeEvent.contentOffset;\n const displacement = y - scrollPositionRef.current.y;\n scrollPositionRef.current = { ...scrollPositionRef.current, y };\n if (displacement !== 0) pan({ x: 0, y: -displacement });\n }}\n >\n <NativeView\n style={{\n height: scrollMapping.vertical.contentSize,\n width: scrollMapping.horizontal.contentSize,\n }}\n >\n {visibleItems.map((item) => {\n const position = worldToViewport(\n { x: item.x, y: item.y },\n { ...viewport, offsetX: 0, offsetY: 0 },\n );\n return (\n <NativeView\n key={item.id}\n style={{\n height: item.height * viewport.pixelsPerUnitY,\n left: position.x + scrollMapping.horizontal.origin,\n position: 'absolute',\n top: position.y + scrollMapping.vertical.origin,\n width: item.width * viewport.pixelsPerUnitX,\n }}\n >\n {renderItem(item)}\n </NativeView>\n );\n })}\n </NativeView>\n </NativeScrollView>\n </NativeScrollView>\n {interactive ? (\n <NativeView accessibilityLabel=\"Viewport controls\" style={controlsStyle}>\n <NativePressable\n accessibilityLabel=\"Pan left\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: 48, y: 0 })}\n >\n <NativeText>←</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Pan right\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: -48, y: 0 })}\n >\n <NativeText>→</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Pan up\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: 0, y: 48 })}\n >\n <NativeText>↑</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Pan down\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: 0, y: -48 })}\n >\n <NativeText>↓</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Zoom in\"\n accessibilityRole=\"button\"\n onPress={() => zoomAt({ x: width / 2, y: height / 2 }, 1.2)}\n >\n <NativeText>+</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Zoom out\"\n accessibilityRole=\"button\"\n onPress={() => zoomAt({ x: width / 2, y: height / 2 }, 1 / 1.2)}\n >\n <NativeText>−</NativeText>\n </NativePressable>\n </NativeView>\n ) : null}\n </NativeView>\n );\n}\n\nconst controlsStyle = { bottom: 8, gap: 4, position: 'absolute' as const, right: 8 };\n\n/*** Builds the initial world position and independent scales for uncontrolled rendering. */\nfunction createInitialViewport(\n width: number,\n height: number,\n zoom: number,\n viewport: GridViewProps['defaultViewport'],\n): GridViewport {\n return {\n height,\n offsetX: viewport?.offsetX ?? 0,\n offsetY: viewport?.offsetY ?? 0,\n pixelsPerUnitX: viewport?.pixelsPerUnitX ?? zoom,\n pixelsPerUnitY: viewport?.pixelsPerUnitY ?? zoom,\n width,\n };\n}\n\n/*** Uses the rendered content extent as the default finite world boundary. */\nfunction createContentConstraints(\n contentWidth: number,\n contentHeight: number,\n): GridViewportConstraints {\n return { world: { height: contentHeight, width: contentWidth, x: 0, y: 0 } };\n}\n\n/*** Maps engine-constrained world offsets to nonnegative native scroll coordinates. */\nfunction createScrollMapping(\n viewport: GridViewport,\n constraints: GridViewportConstraints,\n): ScrollMapping {\n const horizontalMinimum = constrainViewport(\n { ...viewport, offsetX: -Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetX;\n const horizontalMaximum = constrainViewport(\n { ...viewport, offsetX: Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetX;\n const verticalMinimum = constrainViewport(\n { ...viewport, offsetY: -Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetY;\n const verticalMaximum = constrainViewport(\n { ...viewport, offsetY: Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetY;\n return {\n horizontal: createScrollAxisMapping({\n maximum: horizontalMaximum,\n minimum: horizontalMinimum,\n offset: viewport.offsetX,\n scale: viewport.pixelsPerUnitX,\n viewportSize: viewport.width,\n }),\n vertical: createScrollAxisMapping({\n maximum: verticalMaximum,\n minimum: verticalMinimum,\n offset: viewport.offsetY,\n scale: viewport.pixelsPerUnitY,\n viewportSize: viewport.height,\n }),\n };\n}\n\ntype ScrollAxisMappingInput = Readonly<{\n maximum: number;\n minimum: number;\n offset: number;\n scale: number;\n viewportSize: number;\n}>;\n\n/*** Derives a physical scroll axis from the published engine constraint result. */\nfunction createScrollAxisMapping({\n maximum,\n minimum,\n offset,\n scale,\n viewportSize,\n}: ScrollAxisMappingInput): ScrollAxisMapping {\n const range = (maximum - minimum) * scale;\n return {\n contentSize: viewportSize + range,\n origin: -minimum * scale,\n position: (offset - minimum) * scale,\n };\n}\n\n/*** Compares canonical viewport fields without treating equal proposals as state changes. */\nfunction areViewportsEqual(left: GridViewport, right: GridViewport): boolean {\n return (\n left.width === right.width &&\n left.height === right.height &&\n left.offsetX === right.offsetX &&\n left.offsetY === right.offsetY &&\n left.pixelsPerUnitX === right.pixelsPerUnitX &&\n left.pixelsPerUnitY === right.pixelsPerUnitY\n );\n}\n\n/*** Avoids requesting native scrolling again when the physical position is already current. */\nfunction areScrollPositionsEqual(left: ScrollPosition, right: ScrollPosition): boolean {\n return left.x === right.x && left.y === right.y;\n}\n\n/*** Skips a rejected controlled focus proposal until its focus or incoming viewport changes. */\nfunction isRepeatedControlledFocusRevealProposal({\n controlled,\n focusedItemId,\n previous,\n sourceViewport,\n viewport,\n}: Readonly<{\n controlled: boolean;\n focusedItemId: string | undefined;\n previous: FocusRevealProposal | undefined;\n sourceViewport: GridViewport;\n viewport: GridViewport;\n}>): boolean {\n return (\n controlled &&\n focusedItemId !== undefined &&\n previous?.focusedItemId === focusedItemId &&\n areViewportsEqual(previous.sourceViewport, sourceViewport) &&\n areViewportsEqual(previous.viewport, viewport)\n );\n}\n\n/*** Extracts a stable two-finger focal point in the measured outer viewport coordinate space. */\nfunction getPinchGesture(\n touches: readonly Readonly<{\n pageX: number;\n pageY: number;\n }>[],\n width: number,\n height: number,\n viewportOrigin: ViewportOrigin,\n): PinchGesture | undefined {\n const [first, second] = touches;\n if (!first || !second) return undefined;\n const deltaX = second.pageX - first.pageX;\n const deltaY = second.pageY - first.pageY;\n const distance = Math.hypot(deltaX, deltaY);\n if (!Number.isFinite(distance) || distance === 0) return undefined;\n return {\n distance,\n focalPoint: {\n x: Math.min(width, Math.max(0, (first.pageX + second.pageX) / 2 - viewportOrigin.x)),\n y: Math.min(height, Math.max(0, (first.pageY + second.pageY) / 2 - viewportOrigin.y)),\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GridView.js","sourceRoot":"","sources":["../../../../../src/features/grid-view/adapters/inbound/GridView.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n constrainViewport,\n getVisibleGridItems,\n type GridPoint,\n type GridViewport,\n type GridViewportConstraints,\n panViewport,\n revealWorldRect,\n worldToViewport,\n zoomViewportAt,\n} from '@ankhorage/grid-view';\nimport React from 'react';\nimport {\n Pressable as NativePressable,\n ScrollView as NativeScrollView,\n Text as NativeText,\n View as NativeView,\n} from 'react-native';\n\nimport type { GridScrollAxis, GridScrollSync, GridViewProps } from '../../../../types/grid-view';\nimport { createGridScrollSync } from '../../application/createGridScrollSync';\n\ntype PinchGesture = Readonly<{ distance: number; focalPoint: GridPoint }>;\ntype ScrollAxisMapping = Readonly<{ contentSize: number; origin: number; position: number }>;\ntype ScrollMapping = Readonly<{\n horizontal: ScrollAxisMapping;\n vertical: ScrollAxisMapping;\n}>;\ntype ViewportOrigin = Readonly<{ x: number; y: number }>;\ntype FocusRevealProposal = Readonly<{\n focusedItemId: string;\n sourceViewport: GridViewport;\n viewport: GridViewport;\n}>;\ntype PinchTouch = Readonly<{ pageX: number; pageY: number }>;\n\n/*** Renders a controlled or uncontrolled, virtualized 2D world through the canonical grid viewport engine. */\nexport function GridView({\n items,\n contentWidth,\n contentHeight,\n width,\n height,\n viewport: controlledViewport,\n defaultViewport,\n viewportConstraints,\n zoomLimits,\n zoom = 1,\n overscanPixels = 160,\n focusedItemId,\n revealPaddingPixels = 8,\n interactionPolicy,\n onViewportChange,\n onVisibleItemIdsChange,\n renderItem,\n testID,\n}: GridViewProps) {\n const [uncontrolledViewport, setUncontrolledViewport] = React.useState(() =>\n createInitialViewport(width, height, zoom, defaultViewport),\n );\n const horizontalScrollRef = React.useRef<NativeScrollView>(null);\n const verticalScrollRef = React.useRef<NativeScrollView>(null);\n const gridRef = React.useRef<React.ComponentRef<typeof NativeView>>(null);\n const panRef = React.useRef<(displacement: GridPoint) => void>(() => undefined);\n const scrollSyncRef = React.useRef<GridScrollSync | undefined>(undefined);\n const pinchGestureRef = React.useRef<PinchGesture | undefined>(undefined);\n const pinchMeasurementRef = React.useRef(0);\n const pinchSessionRef = React.useRef(0);\n const viewportOriginRef = React.useRef<ViewportOrigin>({ x: 0, y: 0 });\n const focusRevealProposalRef = React.useRef<FocusRevealProposal | undefined>(undefined);\n const focusRevealViewportRef = React.useRef<GridViewport | undefined>(undefined);\n const [isPinching, setIsPinching] = React.useState(false);\n const constraints = React.useMemo(\n () => viewportConstraints ?? createContentConstraints(contentWidth, contentHeight),\n [contentHeight, contentWidth, viewportConstraints],\n );\n const sourceViewport = controlledViewport ?? uncontrolledViewport;\n const viewport = React.useMemo(\n () => constrainViewport({ ...sourceViewport, height, width }, constraints),\n [constraints, height, sourceViewport, width],\n );\n const viewportRef = React.useRef(viewport);\n const visibleItems = React.useMemo(\n () => getVisibleGridItems(items, viewport, overscanPixels),\n [items, overscanPixels, viewport],\n );\n const viewportVisibleIds = React.useMemo(\n () => getVisibleGridItems(visibleItems, viewport).map((item) => item.id),\n [viewport, visibleItems],\n );\n const focusedItem = items.find((item) => item.id === focusedItemId);\n const focusedItemHeight = focusedItem?.height;\n const focusedItemIdForReveal = focusedItem?.id;\n const focusedItemWidth = focusedItem?.width;\n const focusedItemX = focusedItem?.x;\n const focusedItemY = focusedItem?.y;\n const previousVisibleIdsRef = React.useRef<readonly string[]>([]);\n const uncontrolled = controlledViewport === undefined;\n const interactive = interactionPolicy !== 'passive';\n\n const publish = React.useCallback(\n (nextViewport: GridViewport) => {\n if (areViewportsEqual(viewportRef.current, nextViewport)) return;\n viewportRef.current = nextViewport;\n if (uncontrolled) setUncontrolledViewport(nextViewport);\n onViewportChange?.(nextViewport);\n },\n [onViewportChange, uncontrolled],\n );\n const publishRef = React.useRef(publish);\n const pan = (displacement: GridPoint) =>\n publish(panViewport(viewportRef.current, displacement, constraints));\n const zoomAt = (focalPoint: GridPoint, factor: number) =>\n publish(\n zoomViewportAt(\n viewportRef.current,\n focalPoint,\n {\n pixelsPerUnitX: viewportRef.current.pixelsPerUnitX * factor,\n pixelsPerUnitY: viewportRef.current.pixelsPerUnitY * factor,\n },\n zoomLimits,\n constraints,\n ),\n );\n\n React.useEffect(() => {\n viewportRef.current = viewport;\n }, [viewport]);\n\n React.useEffect(() => {\n publishRef.current = publish;\n }, [publish]);\n\n React.useEffect(() => {\n panRef.current = pan;\n });\n\n // Declared before the viewport-sync effect so the arbiter exists when that effect runs.\n React.useEffect(() => {\n const scrollSync = createGridScrollSync({\n onProgrammaticScroll: (axis, displacement) =>\n panRef.current(axis === 'x' ? { x: -displacement, y: 0 } : { x: 0, y: -displacement }),\n onUserScroll: (axis, displacement) =>\n panRef.current(axis === 'x' ? { x: -displacement, y: 0 } : { x: 0, y: -displacement }),\n scrollTo: (axis, offset, animated) => {\n if (axis === 'x') horizontalScrollRef.current?.scrollTo({ animated, x: offset });\n else verticalScrollRef.current?.scrollTo({ animated, y: offset });\n },\n });\n scrollSyncRef.current = scrollSync;\n return () => {\n scrollSync.dispose();\n scrollSyncRef.current = undefined;\n };\n }, []);\n\n /** Routes native scroll events to the arbiter unless a pinch owns the gesture. */\n const handleNativeScroll = (axis: GridScrollAxis, offset: number) => {\n if (!pinchGestureRef.current) scrollSyncRef.current?.scrolled(axis, offset);\n };\n\n const refreshViewportOrigin = React.useCallback(() => {\n gridRef.current?.measureInWindow((x, y) => {\n viewportOriginRef.current = { x, y };\n });\n }, []);\n\n const measurePinchGesture = React.useCallback(\n (\n touches: readonly PinchTouch[],\n session: number,\n onMeasured: (pinch: PinchGesture | undefined) => void,\n ) => {\n const measurement = pinchMeasurementRef.current + 1;\n pinchMeasurementRef.current = measurement;\n gridRef.current?.measureInWindow((x, y) => {\n if (measurement !== pinchMeasurementRef.current || session !== pinchSessionRef.current) {\n return;\n }\n viewportOriginRef.current = { x, y };\n onMeasured(getPinchGesture(touches, width, height, { x, y }));\n });\n },\n [height, width],\n );\n\n React.useLayoutEffect(() => {\n refreshViewportOrigin();\n }, [height, refreshViewportOrigin, width]);\n\n React.useEffect(\n () => () => {\n pinchMeasurementRef.current += 1;\n pinchSessionRef.current += 1;\n },\n [],\n );\n\n React.useEffect(() => {\n if (!onVisibleItemIdsChange) return;\n const previous = previousVisibleIdsRef.current;\n if (\n previous.length === viewportVisibleIds.length &&\n previous.every((id, index) => id === viewportVisibleIds.at(index))\n ) {\n return;\n }\n previousVisibleIdsRef.current = viewportVisibleIds;\n onVisibleItemIdsChange(viewportVisibleIds);\n }, [onVisibleItemIdsChange, viewportVisibleIds]);\n\n React.useEffect(() => {\n const position = createScrollMapping(viewport, constraints);\n const nextPosition = {\n x: position.horizontal.position,\n y: position.vertical.position,\n };\n if (scrollSyncRef.current?.isCurrent(nextPosition)) return;\n const animated =\n focusRevealViewportRef.current !== undefined &&\n areViewportsEqual(viewport, focusRevealViewportRef.current);\n scrollSyncRef.current?.request(nextPosition, animated);\n if (animated) focusRevealViewportRef.current = undefined;\n }, [constraints, viewport]);\n\n React.useEffect(() => {\n if (\n focusedItemHeight === undefined ||\n focusedItemIdForReveal === undefined ||\n focusedItemWidth === undefined ||\n focusedItemX === undefined ||\n focusedItemY === undefined\n ) {\n focusRevealProposalRef.current = undefined;\n return;\n }\n const sourceViewport = viewportRef.current;\n const revealed = revealWorldRect(\n sourceViewport,\n {\n height: focusedItemHeight,\n width: focusedItemWidth,\n x: focusedItemX,\n y: focusedItemY,\n },\n revealPaddingPixels,\n constraints,\n );\n if (\n isRepeatedControlledFocusRevealProposal({\n controlled: !uncontrolled,\n focusedItemId: focusedItemIdForReveal,\n previous: focusRevealProposalRef.current,\n sourceViewport,\n viewport: revealed,\n })\n ) {\n return;\n }\n focusRevealProposalRef.current = {\n focusedItemId: focusedItemIdForReveal,\n sourceViewport,\n viewport: revealed,\n };\n focusRevealViewportRef.current = areViewportsEqual(sourceViewport, revealed)\n ? undefined\n : revealed;\n publishRef.current(revealed);\n }, [\n constraints,\n focusedItemHeight,\n focusedItemIdForReveal,\n focusedItemWidth,\n focusedItemX,\n focusedItemY,\n revealPaddingPixels,\n uncontrolled,\n ]);\n\n const scrollMapping = createScrollMapping(viewport, constraints);\n\n const syncScrollPosition = () => {\n const nextMapping = createScrollMapping(viewportRef.current, constraints);\n const nextPosition = {\n x: nextMapping.horizontal.position,\n y: nextMapping.vertical.position,\n };\n scrollSyncRef.current?.request(nextPosition, false);\n };\n\n return (\n <NativeView\n ref={gridRef}\n accessibilityLabel=\"Interactive grid viewport\"\n onLayout={refreshViewportOrigin}\n onTouchEnd={() => {\n const wasPinching = pinchGestureRef.current !== undefined;\n pinchMeasurementRef.current += 1;\n pinchSessionRef.current += 1;\n pinchGestureRef.current = undefined;\n setIsPinching(false);\n if (wasPinching) syncScrollPosition();\n }}\n onTouchCancel={() => {\n const wasPinching = pinchGestureRef.current !== undefined;\n pinchMeasurementRef.current += 1;\n pinchSessionRef.current += 1;\n pinchGestureRef.current = undefined;\n setIsPinching(false);\n if (wasPinching) syncScrollPosition();\n }}\n onTouchMove={(event) => {\n if (!interactive) return;\n measurePinchGesture([...event.nativeEvent.touches], pinchSessionRef.current, (pinch) => {\n const previous = pinchGestureRef.current;\n pinchGestureRef.current = pinch;\n setIsPinching(pinch !== undefined);\n if (!pinch || !previous) return;\n zoomAt(pinch.focalPoint, pinch.distance / previous.distance);\n });\n }}\n onTouchStart={(event) => {\n const session = pinchSessionRef.current + 1;\n pinchSessionRef.current = session;\n measurePinchGesture([...event.nativeEvent.touches], session, (pinch) => {\n pinchGestureRef.current = pinch;\n setIsPinching(pinch !== undefined);\n });\n }}\n style={{ height, overflow: 'hidden', width }}\n testID={testID}\n >\n <NativeScrollView\n ref={horizontalScrollRef}\n testID={testID ? `${testID}-horizontal-scroll` : undefined}\n horizontal\n scrollEnabled={interactive && !isPinching}\n scrollEventThrottle={16}\n showsHorizontalScrollIndicator\n style={{ height, width }}\n onMomentumScrollEnd={(event) =>\n scrollSyncRef.current?.scrollEnded('x', event.nativeEvent.contentOffset.x)\n }\n onScroll={(event) => handleNativeScroll('x', event.nativeEvent.contentOffset.x)}\n onScrollBeginDrag={(event) =>\n scrollSyncRef.current?.dragBegan('x', event.nativeEvent.contentOffset.x)\n }\n >\n <NativeScrollView\n ref={verticalScrollRef}\n testID={testID ? `${testID}-vertical-scroll` : undefined}\n scrollEnabled={interactive && !isPinching}\n scrollEventThrottle={16}\n showsVerticalScrollIndicator\n style={{ height, width: scrollMapping.horizontal.contentSize }}\n onMomentumScrollEnd={(event) =>\n scrollSyncRef.current?.scrollEnded('y', event.nativeEvent.contentOffset.y)\n }\n onScroll={(event) => handleNativeScroll('y', event.nativeEvent.contentOffset.y)}\n onScrollBeginDrag={(event) =>\n scrollSyncRef.current?.dragBegan('y', event.nativeEvent.contentOffset.y)\n }\n >\n <NativeView\n style={{\n height: scrollMapping.vertical.contentSize,\n width: scrollMapping.horizontal.contentSize,\n }}\n >\n {visibleItems.map((item) => {\n const position = worldToViewport(\n { x: item.x, y: item.y },\n { ...viewport, offsetX: 0, offsetY: 0 },\n );\n return (\n <NativeView\n key={item.id}\n style={{\n height: item.height * viewport.pixelsPerUnitY,\n left: position.x + scrollMapping.horizontal.origin,\n position: 'absolute',\n top: position.y + scrollMapping.vertical.origin,\n width: item.width * viewport.pixelsPerUnitX,\n }}\n >\n {renderItem(item)}\n </NativeView>\n );\n })}\n </NativeView>\n </NativeScrollView>\n </NativeScrollView>\n {interactive ? (\n <NativeView accessibilityLabel=\"Viewport controls\" style={controlsStyle}>\n <NativePressable\n accessibilityLabel=\"Pan left\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: 48, y: 0 })}\n >\n <NativeText>←</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Pan right\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: -48, y: 0 })}\n >\n <NativeText>→</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Pan up\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: 0, y: 48 })}\n >\n <NativeText>↑</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Pan down\"\n accessibilityRole=\"button\"\n onPress={() => pan({ x: 0, y: -48 })}\n >\n <NativeText>↓</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Zoom in\"\n accessibilityRole=\"button\"\n onPress={() => zoomAt({ x: width / 2, y: height / 2 }, 1.2)}\n >\n <NativeText>+</NativeText>\n </NativePressable>\n <NativePressable\n accessibilityLabel=\"Zoom out\"\n accessibilityRole=\"button\"\n onPress={() => zoomAt({ x: width / 2, y: height / 2 }, 1 / 1.2)}\n >\n <NativeText>−</NativeText>\n </NativePressable>\n </NativeView>\n ) : null}\n </NativeView>\n );\n}\n\nconst controlsStyle = { bottom: 8, gap: 4, position: 'absolute' as const, right: 8 };\n\n/*** Builds the initial world position and independent scales for uncontrolled rendering. */\nfunction createInitialViewport(\n width: number,\n height: number,\n zoom: number,\n viewport: GridViewProps['defaultViewport'],\n): GridViewport {\n return {\n height,\n offsetX: viewport?.offsetX ?? 0,\n offsetY: viewport?.offsetY ?? 0,\n pixelsPerUnitX: viewport?.pixelsPerUnitX ?? zoom,\n pixelsPerUnitY: viewport?.pixelsPerUnitY ?? zoom,\n width,\n };\n}\n\n/*** Uses the rendered content extent as the default finite world boundary. */\nfunction createContentConstraints(\n contentWidth: number,\n contentHeight: number,\n): GridViewportConstraints {\n return { world: { height: contentHeight, width: contentWidth, x: 0, y: 0 } };\n}\n\n/*** Maps engine-constrained world offsets to nonnegative native scroll coordinates. */\nfunction createScrollMapping(\n viewport: GridViewport,\n constraints: GridViewportConstraints,\n): ScrollMapping {\n const horizontalMinimum = constrainViewport(\n { ...viewport, offsetX: -Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetX;\n const horizontalMaximum = constrainViewport(\n { ...viewport, offsetX: Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetX;\n const verticalMinimum = constrainViewport(\n { ...viewport, offsetY: -Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetY;\n const verticalMaximum = constrainViewport(\n { ...viewport, offsetY: Number.MAX_SAFE_INTEGER },\n constraints,\n ).offsetY;\n return {\n horizontal: createScrollAxisMapping({\n maximum: horizontalMaximum,\n minimum: horizontalMinimum,\n offset: viewport.offsetX,\n scale: viewport.pixelsPerUnitX,\n viewportSize: viewport.width,\n }),\n vertical: createScrollAxisMapping({\n maximum: verticalMaximum,\n minimum: verticalMinimum,\n offset: viewport.offsetY,\n scale: viewport.pixelsPerUnitY,\n viewportSize: viewport.height,\n }),\n };\n}\n\ntype ScrollAxisMappingInput = Readonly<{\n maximum: number;\n minimum: number;\n offset: number;\n scale: number;\n viewportSize: number;\n}>;\n\n/*** Derives a physical scroll axis from the published engine constraint result. */\nfunction createScrollAxisMapping({\n maximum,\n minimum,\n offset,\n scale,\n viewportSize,\n}: ScrollAxisMappingInput): ScrollAxisMapping {\n const range = (maximum - minimum) * scale;\n return {\n contentSize: viewportSize + range,\n origin: -minimum * scale,\n position: (offset - minimum) * scale,\n };\n}\n\n/*** Compares canonical viewport fields without treating equal proposals as state changes. */\nfunction areViewportsEqual(left: GridViewport, right: GridViewport): boolean {\n return (\n left.width === right.width &&\n left.height === right.height &&\n left.offsetX === right.offsetX &&\n left.offsetY === right.offsetY &&\n left.pixelsPerUnitX === right.pixelsPerUnitX &&\n left.pixelsPerUnitY === right.pixelsPerUnitY\n );\n}\n\n/*** Skips a rejected controlled focus proposal until its focus or incoming viewport changes. */\nfunction isRepeatedControlledFocusRevealProposal({\n controlled,\n focusedItemId,\n previous,\n sourceViewport,\n viewport,\n}: Readonly<{\n controlled: boolean;\n focusedItemId: string | undefined;\n previous: FocusRevealProposal | undefined;\n sourceViewport: GridViewport;\n viewport: GridViewport;\n}>): boolean {\n return (\n controlled &&\n focusedItemId !== undefined &&\n previous?.focusedItemId === focusedItemId &&\n areViewportsEqual(previous.sourceViewport, sourceViewport) &&\n areViewportsEqual(previous.viewport, viewport)\n );\n}\n\n/*** Extracts a stable two-finger focal point in the measured outer viewport coordinate space. */\nfunction getPinchGesture(\n touches: readonly Readonly<{\n pageX: number;\n pageY: number;\n }>[],\n width: number,\n height: number,\n viewportOrigin: ViewportOrigin,\n): PinchGesture | undefined {\n const [first, second] = touches;\n if (!first || !second) return undefined;\n const deltaX = second.pageX - first.pageX;\n const deltaY = second.pageY - first.pageY;\n const distance = Math.hypot(deltaX, deltaY);\n if (!Number.isFinite(distance) || distance === 0) return undefined;\n return {\n distance,\n focalPoint: {\n x: Math.min(width, Math.max(0, (first.pageX + second.pageX) / 2 - viewportOrigin.x)),\n y: Math.min(height, Math.max(0, (first.pageY + second.pageY) / 2 - viewportOrigin.y)),\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GridScrollSync, GridScrollSyncOptions } from '../../../types/grid-view';
|
|
2
|
+
/***
|
|
3
|
+
* Arbitrates each native scroll axis between programmatic requests and the user,
|
|
4
|
+
* so echoes of GridView's own scrollTo calls never become viewport pans.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createGridScrollSync({ scrollTo, onUserScroll, onProgrammaticScroll, now, schedule, cancel, }: GridScrollSyncOptions): GridScrollSync;
|
|
7
|
+
//# sourceMappingURL=createGridScrollSync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGridScrollSync.d.ts","sourceRoot":"","sources":["../../../../src/features/grid-view/application/createGridScrollSync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,cAAc,EACd,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAclC;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,GAAc,EACd,QAAqB,EACrB,MAAqB,GACtB,EAAE,qBAAqB,GAAG,cAAc,CA4GxC"}
|