@ng-native/components 0.3.0 → 0.4.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.
@@ -1,4 +1,3 @@
1
- import 'react-native-gesture-handler';
2
1
  import { NativeGestureBase } from './native-gesture.ts';
3
2
  import * as i0 from "@angular/core";
4
3
  export { type GestureSpec, type GestureTarget } from './gesture-backend.ts';
package/dist/gestures.js CHANGED
@@ -46,15 +46,16 @@
46
46
  * cannot parse, and the rest of the package has to stay loadable in the test suite.
47
47
  */
48
48
  import { Component, Directive, ElementRef, inject } from '@angular/core';
49
- // For the side effect: evaluating the package's index is what starts its event receiver, which
50
- // is what delivers a gesture whose callbacks are ordinary functions. An app importing `Gesture`
51
- // does this too; this file does not depend on that.
52
- import 'react-native-gesture-handler';
53
49
  import { claimHost, nativePlatform, registerViewName } from '@ng-native/fabric';
54
50
  import { gestureDispatcher, } from "./gesture-dispatch.js";
55
51
  import { GESTURES } from "./gesture-backend.js";
56
52
  import { NativeGestureBase } from "./native-gesture.js";
57
53
  import * as i0 from "@angular/core";
54
+ // For the side effect: evaluating the package's index is what starts its event receiver, which
55
+ // is what delivers a gesture whose callbacks are ordinary functions. An app importing `Gesture`
56
+ // does this too; this file does not depend on that. A `require`, so the published types do not
57
+ // name a library a web app may not have installed.
58
+ require('react-native-gesture-handler');
58
59
  export {} from "./gesture-backend.js";
59
60
  /**
60
61
  * The internals, required rather than imported, and each with a literal path because Metro builds
@@ -1 +1 @@
1
- {"version":3,"file":"gestures.js","sourceRoot":"","sources":["../src/gestures.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * react-native-gesture-handler, without React: a native gesture attached to one of our nodes.\n *\n * ```ts\n * import { Gesture } from 'react-native-gesture-handler';\n * import { NativeGesture } from '@ng-native/components/gestures';\n *\n * protected readonly pan = Gesture.Pan().onUpdate((event) => {\n * 'worklet';\n * x.value = event.translationX;\n * });\n * ```\n * ```html\n * <gesture-root>\n * <view [gesture]=\"pan\" [workletStyle]=\"slide\"></view>\n * </gesture-root>\n * ```\n *\n * `GestureDetector` is a React component whose job is to hold a ref, turn it into a view tag, and\n * hand that tag to the native module. Everything under it is a plain function of that tag:\n * `attachHandlers` and `dropHandlers` import no React at runtime, so they are used here as they\n * are, and the gesture objects themselves - `Gesture.Pan()`, the compositions, the config - are\n * the library's own public API and come across untouched.\n *\n * What is written out is the part `useAnimatedGesture` does with hooks: a worklet that turns the\n * raw stream of events into the callbacks a gesture declares. Reanimated's `registerEventHandler`\n * is the same call their `WorkletEventHandler` makes, once per event name per view tag.\n *\n * A gesture whose callbacks are not worklets needs none of that: the library attaches it as a\n * JavaScript-function gesture and its own event receiver, started when the package is first\n * imported, calls them on the JavaScript thread.\n *\n * **A gesture callback must not read `this`, on either thread.** The Babel plugin rewrites one\n * into a worklet whether or not it will run on the UI thread, and a rewritten callback has no\n * `this`; `runOnJS(true)` decides where it runs, not what it may close over. Read what it needs\n * through a local, as a worklet style does.\n *\n * **The internals are reached through `src/`, and that is load-bearing.** Both libraries point\n * their `react-native` package field at their TypeScript source, and Metro prefers that field, so\n * `react-native-gesture-handler` in an app resolves to `src/index.ts`. Importing the built `lib/`\n * copy of a file instead gives a second, parallel copy of the library with its own module state:\n * handlers registered in one copy's registry, the event receiver listening in the other's, and\n * every JavaScript gesture silently doing nothing.\n *\n * Deliberately outside the barrel: everything here reaches React Native's Flow source, which Node\n * cannot parse, and the rest of the package has to stay loadable in the test suite.\n */\nimport { Component, Directive, ElementRef, inject } from '@angular/core';\n// For the side effect: evaluating the package's index is what starts its event receiver, which\n// is what delivers a gesture whose callbacks are ordinary functions. An app importing `Gesture`\n// does this too; this file does not depend on that.\nimport 'react-native-gesture-handler';\nimport { claimHost, nativePlatform, registerViewName, type HostNode } from '@ng-native/fabric';\nimport {\n gestureDispatcher,\n type GestureCallbacks,\n type GestureStateManager,\n} from './gesture-dispatch.ts';\nimport { GESTURES, type GestureBackend } from './gesture-backend.ts';\nimport { NativeGestureBase } from './native-gesture.ts';\n\nexport { type GestureSpec, type GestureTarget } from './gesture-backend.ts';\n\n/**\n * The internals, required rather than imported, and each with a literal path because Metro builds\n * its graph from those.\n *\n * Not for laziness: a static import would put these TypeScript sources into our own type-checking\n * program, where they fail against settings of ours they were never written for\n * (`verbatimModuleSyntax`, `erasableSyntaxOnly`). `require` asks Metro for the module and leaves\n * the compiler out of it, which is the same trade `@ng-native/device` makes for React Native.\n */\nconst { attachHandlers } =\n require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/attachHandlers.ts') as {\n attachHandlers(config: {\n preparedGesture: object;\n gestureConfig: object;\n gesturesToAttach: readonly object[];\n viewTag: number;\n webEventHandlersRef: object;\n }): void;\n };\n\nconst { dropHandlers } =\n require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/dropHandlers.ts') as {\n dropHandlers(prepared: object): void;\n };\n\nconst { maybeInitializeFabric } = require('react-native-gesture-handler/src/init.ts') as {\n maybeInitializeFabric(): void;\n};\n\nconst { GestureStateManager } =\n require('react-native-gesture-handler/src/handlers/gestures/gestureStateManager.ts') as {\n GestureStateManager: { create(handlerTag: number): GestureStateManager };\n };\n\n/**\n * The same call Reanimated's own `WorkletEventHandler` makes: one registration per event name per\n * view tag, which is all a gesture needs to reach the UI runtime. Not public either.\n */\nconst { registerEventHandler, unregisterEventHandler } =\n require('react-native-reanimated/src/core.ts') as {\n registerEventHandler(\n worklet: (event: never) => void,\n eventName: string,\n emitterReactTag: number,\n ): number;\n unregisterEventHandler(id: number): void;\n };\n\n/** The gesture object, as far as this file needs to know it. */\ninterface Attachable {\n initialize(): void;\n prepare(): void;\n toGestureArray(): { handlers: GestureCallbacks; shouldUseReanimated: boolean }[];\n}\n\nconst EVENT_NAMES = ['onGestureHandlerStateChange', 'onGestureHandlerEvent'];\n\n/**\n * A gesture's own state controller, for the touch callbacks: a worklet that accepts or rejects\n * the gesture while it is still being recognised. Wrapped in a worklet of ours because everything\n * the dispatcher closes over is serialised onto the UI runtime with it.\n */\nconst createManager = (handlerTag: number): GestureStateManager => {\n 'worklet';\n return GestureStateManager.create(handlerTag);\n};\n\nconst backend: GestureBackend = {\n attach: (target, gesture) => {\n maybeInitializeFabric();\n const config = gesture as Attachable;\n const gesturesToAttach = config.toGestureArray();\n // The library's own state object. Only `isMounted` is read back by anything of ours - the\n // microtasks `attachHandlers` queues check it, so a directive torn down in the same tick as\n // it was created does not attach a handler nobody will drop.\n const prepared = {\n attachedGestures: [],\n animatedEventHandler: null,\n animatedHandlers: null,\n shouldUseReanimated: gesturesToAttach.some((g) => g.shouldUseReanimated),\n isMounted: true,\n };\n attachHandlers({\n preparedGesture: prepared,\n gestureConfig: config,\n gesturesToAttach,\n viewTag: target.tag,\n // Web only, and there is no web here. The library reads `.current` off it on that platform.\n webEventHandlersRef: { current: {} },\n });\n\n // One dispatcher for both event names, as the library's own event handler is: a gesture's\n // state changes and its updates arrive on different names and share the same state.\n const animated = gesturesToAttach.filter((g) => g.shouldUseReanimated);\n const dispatch = gestureDispatcher(\n animated.map((g) => g.handlers),\n createManager,\n );\n const registrations = animated.length\n ? EVENT_NAMES.map((name) => registerEventHandler(dispatch, name, target.tag))\n : [];\n\n return () => {\n prepared.isMounted = false;\n for (const id of registrations) unregisterEventHandler(id);\n dropHandlers(prepared);\n };\n },\n};\n\n@Directive({\n selector: '[gesture]',\n providers: [{ provide: GESTURES, useValue: backend }],\n})\nexport class NativeGesture extends NativeGestureBase {}\n\n/**\n * The root the gestures are recognised inside. Wrap the app in one, as the library's own\n * `GestureHandlerRootView` is wrapped.\n *\n * **It is a different view on each platform, and that is the library's own split.**\n * `RNGestureHandlerRootView` is an Android view group that intercepts touches before the rest of\n * the tree sees them; on iOS the recognisers hang off the target view itself, the component\n * provider returns nil, and their own root view renders a plain `View`. Registering the native\n * name on both would render an unimplemented component on iOS.\n */\n@Component({ selector: 'gesture-root', template: '<ng-content />' })\nexport class GestureRoot {\n constructor() {\n const android = nativePlatform() === 'android';\n registerViewName('gesture-root', android ? 'RNGestureHandlerRootView' : 'RCTView', {\n flex: 1,\n });\n claimHost(inject(ElementRef).nativeElement as HostNode);\n // The library does this in its root view's render: it installs the JSI bindings the new\n // architecture needs, and it can only happen once Fabric is there to install them into.\n maybeInitializeFabric();\n }\n}\n"]}
1
+ {"version":3,"file":"gestures.js","sourceRoot":"","sources":["../src/gestures.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * react-native-gesture-handler, without React: a native gesture attached to one of our nodes.\n *\n * ```ts\n * import { Gesture } from 'react-native-gesture-handler';\n * import { NativeGesture } from '@ng-native/components/gestures';\n *\n * protected readonly pan = Gesture.Pan().onUpdate((event) => {\n * 'worklet';\n * x.value = event.translationX;\n * });\n * ```\n * ```html\n * <gesture-root>\n * <view [gesture]=\"pan\" [workletStyle]=\"slide\"></view>\n * </gesture-root>\n * ```\n *\n * `GestureDetector` is a React component whose job is to hold a ref, turn it into a view tag, and\n * hand that tag to the native module. Everything under it is a plain function of that tag:\n * `attachHandlers` and `dropHandlers` import no React at runtime, so they are used here as they\n * are, and the gesture objects themselves - `Gesture.Pan()`, the compositions, the config - are\n * the library's own public API and come across untouched.\n *\n * What is written out is the part `useAnimatedGesture` does with hooks: a worklet that turns the\n * raw stream of events into the callbacks a gesture declares. Reanimated's `registerEventHandler`\n * is the same call their `WorkletEventHandler` makes, once per event name per view tag.\n *\n * A gesture whose callbacks are not worklets needs none of that: the library attaches it as a\n * JavaScript-function gesture and its own event receiver, started when the package is first\n * imported, calls them on the JavaScript thread.\n *\n * **A gesture callback must not read `this`, on either thread.** The Babel plugin rewrites one\n * into a worklet whether or not it will run on the UI thread, and a rewritten callback has no\n * `this`; `runOnJS(true)` decides where it runs, not what it may close over. Read what it needs\n * through a local, as a worklet style does.\n *\n * **The internals are reached through `src/`, and that is load-bearing.** Both libraries point\n * their `react-native` package field at their TypeScript source, and Metro prefers that field, so\n * `react-native-gesture-handler` in an app resolves to `src/index.ts`. Importing the built `lib/`\n * copy of a file instead gives a second, parallel copy of the library with its own module state:\n * handlers registered in one copy's registry, the event receiver listening in the other's, and\n * every JavaScript gesture silently doing nothing.\n *\n * Deliberately outside the barrel: everything here reaches React Native's Flow source, which Node\n * cannot parse, and the rest of the package has to stay loadable in the test suite.\n */\nimport { Component, Directive, ElementRef, inject } from '@angular/core';\nimport { claimHost, nativePlatform, registerViewName, type HostNode } from '@ng-native/fabric';\nimport {\n gestureDispatcher,\n type GestureCallbacks,\n type GestureStateManager,\n} from './gesture-dispatch.ts';\nimport { GESTURES, type GestureBackend } from './gesture-backend.ts';\nimport { NativeGestureBase } from './native-gesture.ts';\n\n// For the side effect: evaluating the package's index is what starts its event receiver, which\n// is what delivers a gesture whose callbacks are ordinary functions. An app importing `Gesture`\n// does this too; this file does not depend on that. A `require`, so the published types do not\n// name a library a web app may not have installed.\nrequire('react-native-gesture-handler');\n\nexport { type GestureSpec, type GestureTarget } from './gesture-backend.ts';\n\n/**\n * The internals, required rather than imported, and each with a literal path because Metro builds\n * its graph from those.\n *\n * Not for laziness: a static import would put these TypeScript sources into our own type-checking\n * program, where they fail against settings of ours they were never written for\n * (`verbatimModuleSyntax`, `erasableSyntaxOnly`). `require` asks Metro for the module and leaves\n * the compiler out of it, which is the same trade `@ng-native/device` makes for React Native.\n */\nconst { attachHandlers } =\n require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/attachHandlers.ts') as {\n attachHandlers(config: {\n preparedGesture: object;\n gestureConfig: object;\n gesturesToAttach: readonly object[];\n viewTag: number;\n webEventHandlersRef: object;\n }): void;\n };\n\nconst { dropHandlers } =\n require('react-native-gesture-handler/src/handlers/gestures/GestureDetector/dropHandlers.ts') as {\n dropHandlers(prepared: object): void;\n };\n\nconst { maybeInitializeFabric } = require('react-native-gesture-handler/src/init.ts') as {\n maybeInitializeFabric(): void;\n};\n\nconst { GestureStateManager } =\n require('react-native-gesture-handler/src/handlers/gestures/gestureStateManager.ts') as {\n GestureStateManager: { create(handlerTag: number): GestureStateManager };\n };\n\n/**\n * The same call Reanimated's own `WorkletEventHandler` makes: one registration per event name per\n * view tag, which is all a gesture needs to reach the UI runtime. Not public either.\n */\nconst { registerEventHandler, unregisterEventHandler } =\n require('react-native-reanimated/src/core.ts') as {\n registerEventHandler(\n worklet: (event: never) => void,\n eventName: string,\n emitterReactTag: number,\n ): number;\n unregisterEventHandler(id: number): void;\n };\n\n/** The gesture object, as far as this file needs to know it. */\ninterface Attachable {\n initialize(): void;\n prepare(): void;\n toGestureArray(): { handlers: GestureCallbacks; shouldUseReanimated: boolean }[];\n}\n\nconst EVENT_NAMES = ['onGestureHandlerStateChange', 'onGestureHandlerEvent'];\n\n/**\n * A gesture's own state controller, for the touch callbacks: a worklet that accepts or rejects\n * the gesture while it is still being recognised. Wrapped in a worklet of ours because everything\n * the dispatcher closes over is serialised onto the UI runtime with it.\n */\nconst createManager = (handlerTag: number): GestureStateManager => {\n 'worklet';\n return GestureStateManager.create(handlerTag);\n};\n\nconst backend: GestureBackend = {\n attach: (target, gesture) => {\n maybeInitializeFabric();\n const config = gesture as Attachable;\n const gesturesToAttach = config.toGestureArray();\n // The library's own state object. Only `isMounted` is read back by anything of ours - the\n // microtasks `attachHandlers` queues check it, so a directive torn down in the same tick as\n // it was created does not attach a handler nobody will drop.\n const prepared = {\n attachedGestures: [],\n animatedEventHandler: null,\n animatedHandlers: null,\n shouldUseReanimated: gesturesToAttach.some((g) => g.shouldUseReanimated),\n isMounted: true,\n };\n attachHandlers({\n preparedGesture: prepared,\n gestureConfig: config,\n gesturesToAttach,\n viewTag: target.tag,\n // Web only, and there is no web here. The library reads `.current` off it on that platform.\n webEventHandlersRef: { current: {} },\n });\n\n // One dispatcher for both event names, as the library's own event handler is: a gesture's\n // state changes and its updates arrive on different names and share the same state.\n const animated = gesturesToAttach.filter((g) => g.shouldUseReanimated);\n const dispatch = gestureDispatcher(\n animated.map((g) => g.handlers),\n createManager,\n );\n const registrations = animated.length\n ? EVENT_NAMES.map((name) => registerEventHandler(dispatch, name, target.tag))\n : [];\n\n return () => {\n prepared.isMounted = false;\n for (const id of registrations) unregisterEventHandler(id);\n dropHandlers(prepared);\n };\n },\n};\n\n@Directive({\n selector: '[gesture]',\n providers: [{ provide: GESTURES, useValue: backend }],\n})\nexport class NativeGesture extends NativeGestureBase {}\n\n/**\n * The root the gestures are recognised inside. Wrap the app in one, as the library's own\n * `GestureHandlerRootView` is wrapped.\n *\n * **It is a different view on each platform, and that is the library's own split.**\n * `RNGestureHandlerRootView` is an Android view group that intercepts touches before the rest of\n * the tree sees them; on iOS the recognisers hang off the target view itself, the component\n * provider returns nil, and their own root view renders a plain `View`. Registering the native\n * name on both would render an unimplemented component on iOS.\n */\n@Component({ selector: 'gesture-root', template: '<ng-content />' })\nexport class GestureRoot {\n constructor() {\n const android = nativePlatform() === 'android';\n registerViewName('gesture-root', android ? 'RNGestureHandlerRootView' : 'RCTView', {\n flex: 1,\n });\n claimHost(inject(ElementRef).nativeElement as HostNode);\n // The library does this in its root view's render: it installs the JSI bindings the new\n // architecture needs, and it can only happen once Fabric is there to install them into.\n maybeInitializeFabric();\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -32,7 +32,7 @@ export { TextInput, type KeyboardType, type ReturnKeyType, type SubmitBehavior,
32
32
  export { TouchableOpacity } from './touchable-opacity.ts';
33
33
  export { optionalBoolean, optionalNumber } from './transforms.ts';
34
34
  export { View } from './view.ts';
35
- export { ViewBase, ViewBehavior, contributeAccessibility, type AccessibilityAction, type AccessibilityContribution, type AccessibilityLiveRegion, type AccessibilityRole, type AccessibilityState, type AccessibilityValue, type AndroidDrawable, type ImportantForAccessibility, type PointerEvents, } from './view-base.ts';
35
+ export { ViewBase, ViewBehavior, contributeAccessibility, type AccessibilityAction, type AccessibilityContribution, type AccessibilityLiveRegion, type AccessibilityRole, type Role, type AccessibilityState, type AccessibilityValue, type AndroidDrawable, type ImportantForAccessibility, type PointerEvents, } from './view-base.ts';
36
36
  export { VirtualList, VirtualListRow, VirtualListSeparator, type VirtualItemHeight, type VirtualListSeparatorContext, type VirtualListPadding, type VirtualListVisiblePosition, type VirtualRow, } from './virtual-list.ts';
37
37
  export { type GestureBackend, type GestureSpec, type GestureTarget } from './gesture-backend.ts';
38
38
  export { workletScroll, workletStyle, type SharedValue, type WorkletBackend, type WorkletScrollSpec, type WorkletStyleSpec, type WorkletTarget, } from './worklets.ts';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAmD,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAwCN,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,EAA+D,MAAM,YAAY,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAiC,MAAM,6BAA6B,CAAC;AAClG,OAAO,EAAE,KAAK,EAAsD,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,WAAW,EACX,aAAa,EACb,SAAS,EACT,aAAa,GAGd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAyC,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAyB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAkC,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,WAAW,EACX,WAAW,EACX,gBAAgB,GAOjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAA4C,MAAM,WAAW,CAAC;AAC3E,OAAO,EACL,SAAS,GAIV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,uBAAuB,GAUxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,cAAc,EACd,oBAAoB,GAMrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA6D,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,aAAa,EACb,YAAY,GAMb,MAAM,eAAe,CAAC","sourcesContent":["/**\n * The host primitives, and the platform-capability tokens they inject.\n *\n * Every element a template renders natively is a component here and must be imported by the\n * component whose template uses it, as any Angular component must. A template that uses one\n * without importing it compiles, renders a plain view, and is reported in dev builds.\n *\n * Importing this barrel evaluates decorators, so anything a Node test needs at runtime has to\n * be reached as a source file instead - see the note in `packages/integration-tests/compile.ts`.\n */\nexport { ActivityIndicator } from './activity-indicator.ts';\nexport { type AnimatedPropsHandle, type AnimationBackend } from './animation.ts';\nexport {\n type AccessibilityActionEvent,\n type AccessibilityActionPayload,\n type ContentSizeChangeEvent,\n type ImageErrorEvent,\n type ImageErrorPayload,\n type ImageLoadEvent,\n type ImageLoadPayload,\n type ImageProgressEvent,\n type ImageProgressPayload,\n type Insets,\n type KeyPressEvent,\n type KeyPressPayload,\n type LayoutEvent,\n type LayoutPayload,\n type OrientationChangeEvent,\n type OrientationChangePayload,\n type Point,\n type Rect,\n type ScrollEvent,\n type ScrollPayload,\n type SelectionChangeEvent,\n type SelectionChangePayload,\n type Size,\n type SwitchChangeEvent,\n type SwitchChangePayload,\n type TextInputChangeEvent,\n type TextInputChangePayload,\n type TextInputContentSizeEvent,\n type TextInputContentSizePayload,\n type TextInputEditingEvent,\n type TextInputFocusEvent,\n type TextInputFocusPayload,\n type TextInputScrollEvent,\n type TextInputScrollPayload,\n type TextLayoutEvent,\n type TextLayoutLine,\n type TextLayoutPayload,\n type TouchEvent,\n type TouchEventPayload,\n} from './events.ts';\nexport { Image, type ImageResizeMode, type ImageSource, type ImageURISource } from './image.ts';\nexport { ImageBackground } from './image-background.ts';\nexport { InputAccessoryView } from './input-accessory-view.ts';\nexport {\n KEYBOARD_CONTROLLER,\n KeyboardDock,\n KeyboardLift,\n provideKeyboardController,\n} from './keyboard-dock.ts';\nexport { KeyboardAvoidingView, type KeyboardAvoidingBehavior } from './keyboard-avoiding-view.ts';\nexport { Modal, type ModalOrientation, type ModalPresentationStyle } from './modal.ts';\nexport { NativeRef } from './native-ref.ts';\nexport {\n ControlBase,\n PressBehavior,\n Pressable,\n TouchableBase,\n type AndroidRipple,\n type PressEvent,\n} from './pressable.ts';\nexport { RefreshControl } from './refresh-control.ts';\nexport { type SafeAreaEdge, type SafeAreaEdges } from './safe-area.ts';\nexport { SafeAreaProvider } from './safe-area-provider.ts';\nexport { SafeAreaView, type SafeAreaEdgeMode } from './safe-area-view.ts';\nexport { type KeyboardShouldPersistTaps } from './keyboard-taps.ts';\nexport { ScrollView } from './scroll-view.ts';\nexport {\n SectionEdgeSeparator,\n SectionFooter,\n SectionHeader,\n SectionItem,\n SectionList,\n SectionSeparator,\n type SectionContext,\n type SectionEdgeSeparatorContext,\n type SectionItemContext,\n type SectionListSection,\n type SectionRow,\n type SectionSeparatorContext,\n} from './section-list.ts';\nexport { Switch } from './switch.ts';\nexport { Text, type DynamicTypeRamp, type EllipsizeMode } from './text.ts';\nexport {\n TextInput,\n type KeyboardType,\n type ReturnKeyType,\n type SubmitBehavior,\n} from './text-input.ts';\nexport { TouchableOpacity } from './touchable-opacity.ts';\nexport { optionalBoolean, optionalNumber } from './transforms.ts';\nexport { View } from './view.ts';\nexport {\n ViewBase,\n ViewBehavior,\n contributeAccessibility,\n type AccessibilityAction,\n type AccessibilityContribution,\n type AccessibilityLiveRegion,\n type AccessibilityRole,\n type AccessibilityState,\n type AccessibilityValue,\n type AndroidDrawable,\n type ImportantForAccessibility,\n type PointerEvents,\n} from './view-base.ts';\nexport {\n VirtualList,\n VirtualListRow,\n VirtualListSeparator,\n type VirtualItemHeight,\n type VirtualListSeparatorContext,\n type VirtualListPadding,\n type VirtualListVisiblePosition,\n type VirtualRow,\n} from './virtual-list.ts';\nexport { type GestureBackend, type GestureSpec, type GestureTarget } from './gesture-backend.ts';\nexport {\n workletScroll,\n workletStyle,\n type SharedValue,\n type WorkletBackend,\n type WorkletScrollSpec,\n type WorkletStyleSpec,\n type WorkletTarget,\n} from './worklets.ts';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAmD,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAwCN,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,EAA+D,MAAM,YAAY,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAiC,MAAM,6BAA6B,CAAC;AAClG,OAAO,EAAE,KAAK,EAAsD,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,WAAW,EACX,aAAa,EACb,SAAS,EACT,aAAa,GAGd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAyC,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAyB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAkC,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,WAAW,EACX,WAAW,EACX,gBAAgB,GAOjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAA4C,MAAM,WAAW,CAAC;AAC3E,OAAO,EACL,SAAS,GAIV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,uBAAuB,GAWxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,cAAc,EACd,oBAAoB,GAMrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA6D,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,aAAa,EACb,YAAY,GAMb,MAAM,eAAe,CAAC","sourcesContent":["/**\n * The host primitives, and the platform-capability tokens they inject.\n *\n * Every element a template renders natively is a component here and must be imported by the\n * component whose template uses it, as any Angular component must. A template that uses one\n * without importing it compiles, renders a plain view, and is reported in dev builds.\n *\n * Importing this barrel evaluates decorators, so anything a Node test needs at runtime has to\n * be reached as a source file instead - see the note in `packages/integration-tests/compile.ts`.\n */\nexport { ActivityIndicator } from './activity-indicator.ts';\nexport { type AnimatedPropsHandle, type AnimationBackend } from './animation.ts';\nexport {\n type AccessibilityActionEvent,\n type AccessibilityActionPayload,\n type ContentSizeChangeEvent,\n type ImageErrorEvent,\n type ImageErrorPayload,\n type ImageLoadEvent,\n type ImageLoadPayload,\n type ImageProgressEvent,\n type ImageProgressPayload,\n type Insets,\n type KeyPressEvent,\n type KeyPressPayload,\n type LayoutEvent,\n type LayoutPayload,\n type OrientationChangeEvent,\n type OrientationChangePayload,\n type Point,\n type Rect,\n type ScrollEvent,\n type ScrollPayload,\n type SelectionChangeEvent,\n type SelectionChangePayload,\n type Size,\n type SwitchChangeEvent,\n type SwitchChangePayload,\n type TextInputChangeEvent,\n type TextInputChangePayload,\n type TextInputContentSizeEvent,\n type TextInputContentSizePayload,\n type TextInputEditingEvent,\n type TextInputFocusEvent,\n type TextInputFocusPayload,\n type TextInputScrollEvent,\n type TextInputScrollPayload,\n type TextLayoutEvent,\n type TextLayoutLine,\n type TextLayoutPayload,\n type TouchEvent,\n type TouchEventPayload,\n} from './events.ts';\nexport { Image, type ImageResizeMode, type ImageSource, type ImageURISource } from './image.ts';\nexport { ImageBackground } from './image-background.ts';\nexport { InputAccessoryView } from './input-accessory-view.ts';\nexport {\n KEYBOARD_CONTROLLER,\n KeyboardDock,\n KeyboardLift,\n provideKeyboardController,\n} from './keyboard-dock.ts';\nexport { KeyboardAvoidingView, type KeyboardAvoidingBehavior } from './keyboard-avoiding-view.ts';\nexport { Modal, type ModalOrientation, type ModalPresentationStyle } from './modal.ts';\nexport { NativeRef } from './native-ref.ts';\nexport {\n ControlBase,\n PressBehavior,\n Pressable,\n TouchableBase,\n type AndroidRipple,\n type PressEvent,\n} from './pressable.ts';\nexport { RefreshControl } from './refresh-control.ts';\nexport { type SafeAreaEdge, type SafeAreaEdges } from './safe-area.ts';\nexport { SafeAreaProvider } from './safe-area-provider.ts';\nexport { SafeAreaView, type SafeAreaEdgeMode } from './safe-area-view.ts';\nexport { type KeyboardShouldPersistTaps } from './keyboard-taps.ts';\nexport { ScrollView } from './scroll-view.ts';\nexport {\n SectionEdgeSeparator,\n SectionFooter,\n SectionHeader,\n SectionItem,\n SectionList,\n SectionSeparator,\n type SectionContext,\n type SectionEdgeSeparatorContext,\n type SectionItemContext,\n type SectionListSection,\n type SectionRow,\n type SectionSeparatorContext,\n} from './section-list.ts';\nexport { Switch } from './switch.ts';\nexport { Text, type DynamicTypeRamp, type EllipsizeMode } from './text.ts';\nexport {\n TextInput,\n type KeyboardType,\n type ReturnKeyType,\n type SubmitBehavior,\n} from './text-input.ts';\nexport { TouchableOpacity } from './touchable-opacity.ts';\nexport { optionalBoolean, optionalNumber } from './transforms.ts';\nexport { View } from './view.ts';\nexport {\n ViewBase,\n ViewBehavior,\n contributeAccessibility,\n type AccessibilityAction,\n type AccessibilityContribution,\n type AccessibilityLiveRegion,\n type AccessibilityRole,\n type Role,\n type AccessibilityState,\n type AccessibilityValue,\n type AndroidDrawable,\n type ImportantForAccessibility,\n type PointerEvents,\n} from './view-base.ts';\nexport {\n VirtualList,\n VirtualListRow,\n VirtualListSeparator,\n type VirtualItemHeight,\n type VirtualListSeparatorContext,\n type VirtualListPadding,\n type VirtualListVisiblePosition,\n type VirtualRow,\n} from './virtual-list.ts';\nexport { type GestureBackend, type GestureSpec, type GestureTarget } from './gesture-backend.ts';\nexport {\n workletScroll,\n workletStyle,\n type SharedValue,\n type WorkletBackend,\n type WorkletScrollSpec,\n type WorkletStyleSpec,\n type WorkletTarget,\n} from './worklets.ts';\n"]}
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Press handling, built on the engine's responder system as RN's `Pressability` is.
3
+ *
4
+ * `onPress` is not a native event: RN synthesises it in JS from the touch primitives, with a
5
+ * press rectangle, delays and a long-press timer around them. This is that machine, on the same
6
+ * responder negotiation, so a button and an enclosing scroll view agree on who owns a drag.
7
+ */
8
+ import { type Signal } from '@angular/core';
1
9
  import type { Insets, TouchEvent } from './events.ts';
2
10
  import { ViewBase } from './view-base.ts';
3
11
  import * as i0 from "@angular/core";
@@ -225,8 +233,23 @@ export declare abstract class ControlBase extends TouchableBase {
225
233
  * read `pressed` without caring whether it landed on this or on a real `<pressable>`.
226
234
  */
227
235
  export declare class PressBehavior extends ControlBase {
236
+ /** The conditions the composing component gave, any of which disables the control. */
237
+ private readonly conditions;
238
+ private readonly held;
239
+ /**
240
+ * Disable the control while `condition` is true, from the component that composes this: a
241
+ * button that is loading, which its caller's `disabled` knows nothing of. Either one disables
242
+ * it, as `disabled={loading || disabled}` does on React Native's `Pressable`: presses are
243
+ * refused, a stylesheet sees `[data-disabled]`, and a screen reader is told.
244
+ *
245
+ * constructor() {
246
+ * inject(PressBehavior).disableWhile(this.loading);
247
+ * }
248
+ */
249
+ disableWhile(condition: Signal<boolean>): void;
228
250
  protected accessibleByDefault(): boolean;
229
251
  protected focusableByDefault(): boolean;
252
+ protected pressDisabled(): boolean;
230
253
  protected disabledForAccessibility(): boolean | undefined;
231
254
  static ɵfac: i0.ɵɵFactoryDeclaration<PressBehavior, never>;
232
255
  static ɵdir: i0.ɵɵDirectiveDeclaration<PressBehavior, never, never, {}, {}, never, never, true, never>;
package/dist/pressable.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * press rectangle, delays and a long-press timer around them. This is that machine, on the same
6
6
  * responder negotiation, so a button and an enclosing scroll view agree on who owns a drag.
7
7
  */
8
- import { Directive, booleanAttribute, forwardRef, input, numberAttribute, output, signal, } from '@angular/core';
8
+ import { Directive, booleanAttribute, computed, forwardRef, input, numberAttribute, output, signal, } from '@angular/core';
9
9
  import { nativePlatform } from '@ng-native/fabric';
10
10
  import { optionalBoolean } from "./transforms.js";
11
11
  import { ViewBase } from "./view-base.js";
@@ -459,7 +459,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
459
459
  */
460
460
  export class ControlBase extends TouchableBase {
461
461
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: ControlBase, deps: null, target: i0.ɵɵFactoryTarget.Directive });
462
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: ControlBase, isStandalone: true, host: { properties: { "accessibilityState": "accessibilityStateProp()", "attr.data-disabled": "disabled() ? '' : null", "nativeBackgroundAndroid": "rippleBackground()", "nativeForegroundAndroid": "rippleForeground()" } }, usesInheritance: true, ngImport: i0 });
462
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: ControlBase, isStandalone: true, host: { properties: { "accessibilityState": "accessibilityStateProp()", "attr.data-disabled": "pressDisabled() ? '' : null", "nativeBackgroundAndroid": "rippleBackground()", "nativeForegroundAndroid": "rippleForeground()" } }, usesInheritance: true, ngImport: i0 });
463
463
  }
464
464
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: ControlBase, decorators: [{
465
465
  type: Directive,
@@ -469,7 +469,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
469
469
  // the one binding that keeps the announced state in step with it.
470
470
  '[accessibilityState]': 'accessibilityStateProp()',
471
471
  // Nor is it left on the node for `:disabled` to read, so this is what a stylesheet matches.
472
- '[attr.data-disabled]': "disabled() ? '' : null",
472
+ '[attr.data-disabled]': "pressDisabled() ? '' : null",
473
473
  '[nativeBackgroundAndroid]': 'rippleBackground()',
474
474
  '[nativeForegroundAndroid]': 'rippleForeground()',
475
475
  },
@@ -488,14 +488,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
488
488
  * read `pressed` without caring whether it landed on this or on a real `<pressable>`.
489
489
  */
490
490
  export class PressBehavior extends ControlBase {
491
+ /** The conditions the composing component gave, any of which disables the control. */
492
+ conditions = signal([], /* @ts-ignore */
493
+ ...(ngDevMode ? [{ debugName: "conditions" }] : /* istanbul ignore next */ []));
494
+ held = computed(() => this.conditions().some((condition) => condition()), /* @ts-ignore */
495
+ ...(ngDevMode ? [{ debugName: "held" }] : /* istanbul ignore next */ []));
496
+ /**
497
+ * Disable the control while `condition` is true, from the component that composes this: a
498
+ * button that is loading, which its caller's `disabled` knows nothing of. Either one disables
499
+ * it, as `disabled={loading || disabled}` does on React Native's `Pressable`: presses are
500
+ * refused, a stylesheet sees `[data-disabled]`, and a screen reader is told.
501
+ *
502
+ * constructor() {
503
+ * inject(PressBehavior).disableWhile(this.loading);
504
+ * }
505
+ */
506
+ disableWhile(condition) {
507
+ this.conditions.update((conditions) => [...conditions, condition]);
508
+ }
491
509
  accessibleByDefault() {
492
510
  return true;
493
511
  }
494
512
  focusableByDefault() {
495
513
  return true;
496
514
  }
515
+ pressDisabled() {
516
+ return this.held() || super.pressDisabled();
517
+ }
497
518
  disabledForAccessibility() {
498
- return this.disabled();
519
+ return this.held() ? true : this.disabled();
499
520
  }
500
521
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: PressBehavior, deps: null, target: i0.ɵɵFactoryTarget.Directive });
501
522
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: PressBehavior, isStandalone: true, providers: [{ provide: TouchableBase, useExisting: forwardRef(() => PressBehavior) }], usesInheritance: true, ngImport: i0 });
@@ -1 +1 @@
1
- {"version":3,"file":"pressable.js","sourceRoot":"","sources":["../src/pressable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Press handling, built on the engine's responder system as RN's `Pressability` is.\n *\n * `onPress` is not a native event: RN synthesises it in JS from the touch primitives, with a\n * press rectangle, delays and a long-press timer around them. This is that machine, on the same\n * responder negotiation, so a button and an enclosing scroll view agree on who owns a drag.\n */\nimport {\n Directive,\n booleanAttribute,\n forwardRef,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\nimport { nativePlatform, type NativeSyntheticEvent } from '@ng-native/fabric';\nimport type { Insets, TouchEvent } from './events.ts';\nimport { optionalBoolean } from './transforms.ts';\nimport { ViewBase } from './view-base.ts';\n\n/** What a press handler receives: RN's `{nativeEvent}` shape, passed straight through. */\nexport type PressEvent = TouchEvent;\n\n/**\n * Android's ripple, drawn natively. `foreground` paints it over the content rather than behind.\n */\nexport interface AndroidRipple {\n readonly color?: string | number;\n readonly borderless?: boolean;\n readonly radius?: number;\n readonly foreground?: boolean;\n}\n\n/**\n * How far outside its own bounds a control keeps a press: RN's `DEFAULT_PRESS_RECT_OFFSETS`.\n * More room below, because a thumb rolls downwards as it lifts.\n */\nconst DEFAULT_PRESS_RETENTION: Required<Insets> = { top: 20, left: 20, right: 20, bottom: 30 };\n/** RN's `DEFAULT_LONG_PRESS_DELAY_MS`. */\nconst DEFAULT_LONG_PRESS_DELAY = 500;\n/** RN's `DEFAULT_MIN_PRESS_DURATION`: the pressed look stays at least this long on a quick tap. */\nconst DEFAULT_MIN_PRESS_DURATION = 130;\n\n/**\n * Used only until a control has been measured. RN measures the view and cancels when the touch\n * leaves its bounds plus the retention offset; before the first layout arrives there are no\n * bounds to compare against, so fall back to a small movement threshold rather than treating a\n * drag of any length as a tap.\n */\nconst PRESS_CANCEL_DISTANCE = 15;\n\nconst insets = (value: Insets | number | undefined, fallback: Required<Insets>) => {\n if (value === undefined) return fallback;\n if (typeof value === 'number') return { top: value, left: value, right: value, bottom: value };\n return {\n top: value.top ?? 0,\n left: value.left ?? 0,\n right: value.right ?? 0,\n bottom: value.bottom ?? 0,\n };\n};\n\n/** Page-space touch point, tolerating the several shapes a Fabric touch payload can take. */\nfunction touchPoint(event: NativeSyntheticEvent): { x: number; y: number } {\n const native = (event.nativeEvent ?? {}) as {\n pageX?: number;\n pageY?: number;\n touches?: { pageX?: number; pageY?: number }[];\n };\n const touch = native.touches?.[0];\n return {\n x: native.pageX ?? touch?.pageX ?? 0,\n y: native.pageY ?? touch?.pageY ?? 0,\n };\n}\n\n/** What `rippleDrawable` builds: Android's `RippleAndroid` drawable description. */\ninterface RippleDrawable {\n readonly type: 'RippleAndroid';\n readonly color: unknown;\n readonly borderless: boolean;\n readonly rippleRadius: number | undefined;\n}\n\nconst now = (): number => globalThis.performance?.now?.() ?? Date.now();\n\n/**\n * The press machine, and the base of every primitive that takes a touch.\n *\n * It declares no host bindings of its own, because `Text` extends it and a host binding runs on\n * every element that carries it, on every pass. The controls bind theirs through `ControlBase`.\n */\n@Directive()\nexport abstract class TouchableBase extends ViewBase {\n /**\n * Ignore touches entirely. Undefined until set, because React Native tells \"not passed\" from\n * \"passed false\": only a passed `disabled` wins over `aria-disabled` in what is announced.\n */\n readonly disabled = input(undefined, { transform: optionalBoolean });\n\n /**\n * How far outside the hit area a touch may wander before the press is cancelled. Native's\n * `hitSlop` grows the area a touch can start in; this grows the area it may move within.\n */\n readonly pressRetentionOffset = input<Insets | number>();\n /** Milliseconds a touch must be held before `(longPress)` fires. */\n readonly delayLongPress = input(DEFAULT_LONG_PRESS_DELAY, { transform: numberAttribute });\n /** Milliseconds between the touch landing and `(pressIn)`, so a scroll can start first. */\n readonly delayPressIn = input(0, { transform: numberAttribute });\n /** Milliseconds between the touch lifting and `(pressOut)`. */\n readonly delayPressOut = input(0, { transform: numberAttribute });\n /** The pressed state lasts at least this long, so a quick tap still shows it. */\n readonly minPressDuration = input(DEFAULT_MIN_PRESS_DURATION, { transform: numberAttribute });\n /** Whether a scrolling ancestor may take the gesture away mid-press. */\n readonly cancelable = input(true, { transform: booleanAttribute });\n /** Android: a native ripple on press. */\n readonly androidRipple = input<AndroidRipple>(undefined, { alias: 'android_ripple' });\n\n /** The touch lifted inside the press area. Not fired after a `(longPress)` that has a listener. */\n readonly press = output<PressEvent>();\n readonly pressIn = output<PressEvent>();\n readonly pressOut = output<PressEvent>();\n /**\n * The touch has been held for `delayLongPress`. With no listener there is no long press, as in\n * React Native, so a slow tap is still a `press`.\n */\n readonly longPress = output<PressEvent>();\n\n /** Whether a press is in progress, for the pressed look. */\n readonly pressed = signal(false);\n\n /**\n * Whether a pointer is over the control, which on this platform means an iPad with a trackpad\n * or a mouse. Always false on a phone, because a phone never sends a pointer event.\n *\n * Opted into by exactly the elements that opt into being measured, which is the same question\n * asked twice: is this a control, or is it a piece of text that merely inherits the machinery.\n * Registering on everything was the first attempt and put two props on every paragraph on\n * screen, which is the most numerous node in an app paying for a state a label cannot use.\n */\n readonly hovered = signal(false);\n\n /*\n * Methods rather than `computed()`s, because nearly every instance has no ripple and a computed\n * is an allocation per element whether or not it ever holds anything. The drawable is kept for as\n * long as the ripple it came from, which is the memo the computed was there to provide: a fresh\n * object on every pass would re-send the prop on every pass.\n */\n protected rippleBackground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple && !ripple.foreground ? this.drawable(ripple) : undefined;\n }\n\n protected rippleForeground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple?.foreground ? this.drawable(ripple) : undefined;\n }\n\n private drawn: { ripple: AndroidRipple; drawable: RippleDrawable } | null = null;\n\n private drawable(ripple: AndroidRipple): RippleDrawable {\n if (this.drawn?.ripple !== ripple)\n this.drawn = { ripple, drawable: this.rippleDrawable(ripple) };\n return this.drawn.drawable;\n }\n\n /**\n * The drawable description Android's `ReactDrawableHelper` reads.\n *\n * `color` goes through the engine the way every other colour prop does, and has to: the helper\n * switches on the value's runtime type and takes a number or a platform-colour map, and anything\n * else - a `'#ff0000'` written at the call site, say - falls through to `null` and the ripple\n * draws in the theme's own `colorControlHighlight` instead. Nothing is logged and nothing throws,\n * so the ripple appears and is simply the wrong colour. RN's own `TouchableNativeFeedback.Ripple`\n * calls `processColor` here for the same reason.\n */\n private rippleDrawable(ripple: AndroidRipple): RippleDrawable {\n return {\n type: 'RippleAndroid' as const,\n color: this.engine.color(ripple.color),\n borderless: ripple.borderless ?? false,\n rippleRadius: ripple.radius,\n };\n }\n\n /** Where the touch started, so a drag can be told apart from a tap. */\n private origin: { x: number; y: number } | null = null;\n /** The control's own size, from its last layout. Null until it has been measured once. */\n private size: { width: number; height: number } | null = null;\n private cancelled = false;\n private longPressed = false;\n /** How many `(longPress)` listeners there are; the long-press clock only runs with one. */\n private longPressListeners = 0;\n private pressedAt = 0;\n private pressInTimer: ReturnType<typeof setTimeout> | null = null;\n private longPressTimer: ReturnType<typeof setTimeout> | null = null;\n private pressOutTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n super();\n // output() has to be a member's own initializer for the compiler to see it, so its listeners\n // are counted here, through its public subscribe.\n const subscribe = this.longPress.subscribe.bind(this.longPress);\n this.longPress.subscribe = (callback) => {\n this.longPressListeners++;\n const subscription = subscribe(callback);\n let open = true;\n return {\n unsubscribe: () => {\n if (open) this.longPressListeners--;\n open = false;\n subscription.unsubscribe();\n },\n };\n };\n }\n\n /** Called as a press starts and ends, for a subclass that shows it natively. `Text` does. */\n protected pressedChanged(_pressed: boolean): void {}\n\n /** Whether a touch starting on this node should be claimed. `Text` narrows it. */\n protected claims(): boolean {\n return !this.pressDisabled();\n }\n\n /**\n * Whether presses are refused. `Pressable.js` gives Pressability `disabled` alone, so here\n * `aria-disabled` and `accessibilityState.disabled` change what is announced and nothing else.\n * `TouchableOpacity` and `Text` widen it.\n */\n protected pressDisabled(): boolean {\n return !!this.disabled();\n }\n\n /**\n * `TouchableOpacity.js` and `Text.js`: `disabled ?? aria-disabled ?? accessibilityState.disabled`,\n * which is the merged announced state whenever `disabled` is unset.\n */\n protected disabledByAnyState(): boolean {\n return (this.disabled() ?? this.accessibilityStateProp()?.disabled) === true;\n }\n\n /**\n * Whether the control's size should be tracked. Native only measures a view that asks, so\n * this must not be true for every `<text>`: a pressable text opts in, a label never does.\n */\n protected measures(): boolean {\n return true;\n }\n\n /**\n * Whether a touch this far from where it started is still on the control.\n *\n * Distance from the origin is the wrong question on anything large: a thumb tap on a full-width\n * button easily travels twenty points without ever leaving it, and cancelling there reads as\n * \"the button doesn't work\", intermittently and only for some people. What matters is whether\n * the finger is still within the control plus its hit slop, plus the slop RN allows.\n *\n * The touch began somewhere inside the control but we do not know where, so the bound is the\n * full extent rather than half of it. That errs towards keeping the press, which is the right\n * way to be wrong: a press that survives a drag the user meant as a scroll is a smaller sin\n * than a tap that does nothing.\n */\n private stillOnControl(dx: number, dy: number): boolean {\n if (!this.size) return Math.hypot(dx, dy) <= PRESS_CANCEL_DISTANCE;\n const slop = insets(this.hitSlop(), { top: 0, left: 0, right: 0, bottom: 0 });\n const keep = insets(this.pressRetentionOffset(), DEFAULT_PRESS_RETENTION);\n const horizontal = dx < 0 ? slop.left + keep.left : slop.right + keep.right;\n const vertical = dy < 0 ? slop.top + keep.top : slop.bottom + keep.bottom;\n return (\n Math.abs(dx) <= this.size.width + horizontal && Math.abs(dy) <= this.size.height + vertical\n );\n }\n\n /**\n * A lifecycle hook rather than `inject(DestroyRef).onDestroy`: Angular registers a hook once per\n * directive type, where the callback was a closure and a lookup for every instance - and every\n * `<text>` on screen is one.\n */\n ngOnDestroy(): void {\n this.clearTimers();\n this.stopResponding?.();\n this.stopLayout?.();\n this.stopHover?.();\n this.stopClick?.();\n }\n\n private stopResponding: (() => void) | null = null;\n private stopLayout: (() => void) | null = null;\n private stopHover: (() => void) | null = null;\n private stopClick: (() => void) | null = null;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n this.clickIfNeeded();\n }\n\n override ngOnChanges(): void {\n super.ngOnChanges();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n this.clickIfNeeded();\n }\n\n /**\n * A press with no touch: Android's `performClick()`, which is what Enter, the D-pad centre and\n * TalkBack's double-tap do to a focused view, and which reaches us as `topClick` alone.\n *\n * `Pressability.js` answers it in `onClick`: `onPress` and nothing around it, not while disabled,\n * and not for a click carrying a `pointerType`, which is the pointer event a touch already\n * pressed through. It presses only the view that was clicked: a touchable the click only bubbled\n * through stops it there, so neither it nor anything above it acts on a click meant for a\n * focusable view inside it.\n *\n * Android only. iOS sends a click only as a pointer event, and the web host binds `topClick` to\n * the DOM's own click, which a mouse press already reached through the responder.\n */\n private clickIfNeeded(): void {\n if (this.stopClick || !this.measures() || nativePlatform() !== 'android') return;\n this.stopClick = this.engine.setEventListener(this.node, 'topClick', (event) => {\n const click = event as PressEvent;\n if (!this.measures() || Object.hasOwn(click.nativeEvent ?? {}, 'pointerType')) return;\n if (click.target !== this.node) {\n click.stopPropagation();\n return;\n }\n if (this.claims()) this.press.emit(click);\n });\n }\n\n /**\n * Join the responder negotiation, once this is something a touch can press.\n *\n * Behind `measures()` for the same reason as layout and hover: a `<text>` is the commonest node\n * on screen and almost never a control, and registering every one cost a handler object, six\n * closures and a responder entry apiece for a touch it would have refused anyway.\n */\n private respondIfNeeded(): void {\n if (this.stopResponding || !this.measures()) return;\n this.stopResponding = this.engine.setResponder(this.node, {\n // Claim the gesture on touch down unless disabled. Because this goes through the\n // negotiation, an ancestor can pre-empt us in the capture pass and a nested pressable\n // wins over us in the bubble pass, neither of which raw touch listeners could express.\n onStartShouldSetResponder: () => this.claims(),\n onResponderGrant: (event) => this.onGrant(event),\n onResponderMove: (event) => this.onMove(event),\n onResponderRelease: (event) => this.onRelease(event),\n onResponderTerminate: (event) => this.onTerminate(event),\n // Yield to an enclosing scroll view when it takes over the drag, unless told not to.\n onResponderTerminationRequest: () => this.cancelable(),\n });\n }\n\n /**\n * `onLayout` is opted into by the engine as soon as something listens for it, which is the only\n * way the native side reports a view's size at all, and the reason it is only asked for once\n * `measures()` says so - a `<text>` answers that from an input, and most of them say no.\n *\n * Called from the lifecycle rather than watched by an effect. An effect per element is an\n * allocation and a scheduler entry for every pressable and every piece of text on screen, to\n * notice a change these two hooks already see.\n */\n /**\n * Hover, on the same terms and behind the same question.\n *\n * Fabric will not dispatch a pointer event to a view whose props have not asked for one, and\n * the engine writes those props when something listens - so listening is the whole opt-in. The\n * gate is `measures()`, which is not what its name is about but is the right question underneath\n * it: is this an actual control, or a piece of text that merely inherits the machinery. A label\n * says no, and two props on every paragraph on screen is not a cost worth paying for a hover\n * state a label has no use for.\n *\n * Never true on a phone, which sends no pointer events at all. This is the one thing an iPad\n * with a trackpad has that a phone does not.\n */\n private hoverIfNeeded(): void {\n if (this.stopHover || !this.measures()) return;\n const enter = this.engine.setEventListener(this.node, 'topPointerEnter', () =>\n this.hovered.set(true),\n );\n const leave = this.engine.setEventListener(this.node, 'topPointerLeave', () =>\n this.hovered.set(false),\n );\n this.stopHover = () => {\n enter();\n leave();\n };\n }\n\n private measureIfNeeded(): void {\n if (this.stopLayout || !this.measures()) return;\n this.stopLayout = this.engine.setEventListener(this.node, 'topLayout', (event) => {\n const layout = (event as NativeSyntheticEvent<{ layout?: { width: number; height: number } }>)\n .nativeEvent?.layout;\n if (layout) this.size = { width: layout.width, height: layout.height };\n });\n }\n\n private onGrant(event: PressEvent): void {\n this.origin = touchPoint(event);\n this.cancelled = false;\n this.longPressed = false;\n this.clearTimers();\n if (this.androidRipple()) {\n const { x, y } = this.origin;\n this.engine.dispatchCommand(this.node, 'hotspotUpdate', [x, y]);\n this.engine.dispatchCommand(this.node, 'setPressed', [true]);\n }\n const delay = this.delayPressIn();\n if (delay > 0) this.pressInTimer = setTimeout(() => this.activate(event), delay);\n else this.activate(event);\n }\n\n /** `pressIn`, and the long-press clock starts from here. */\n private activate(event: PressEvent): void {\n this.pressInTimer = null;\n this.pressedAt = now();\n this.pressed.set(true);\n this.pressedChanged(true);\n this.pressIn.emit(event);\n if (!this.longPressListeners) return;\n this.longPressTimer = setTimeout(() => {\n this.longPressTimer = null;\n this.longPressed = true;\n this.longPress.emit(event);\n }, this.delayLongPress());\n }\n\n private onMove(event: PressEvent): void {\n if (this.cancelled || !this.origin) return;\n const point = touchPoint(event);\n if (this.stillOnControl(point.x - this.origin.x, point.y - this.origin.y)) return;\n // The finger has wandered: this is a drag, not a tap. Give up the press but stay the\n // responder, so a scroll view underneath still gets its gesture.\n this.cancelled = true;\n this.deactivate(event);\n }\n\n private onRelease(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n // Lifted before the press-in delay ran out: RN still reports a full press.\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.activate(event);\n }\n const longPressed = this.longPressed;\n this.deactivate(event);\n if (!longPressed) this.press.emit(event);\n }\n\n private onTerminate(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n this.cancelled = true;\n this.deactivate(event);\n }\n\n /** `pressOut`, no sooner than `minPressDuration` after `pressIn` and after `delayPressOut`. */\n private deactivate(event: PressEvent): void {\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.pressInTimer = null;\n return;\n }\n if (this.longPressTimer) {\n clearTimeout(this.longPressTimer);\n this.longPressTimer = null;\n }\n if (!this.pressed()) return;\n const held = now() - this.pressedAt;\n const delay = Math.max(this.delayPressOut(), this.minPressDuration() - held);\n const out = () => {\n this.pressOutTimer = null;\n this.pressed.set(false);\n this.pressedChanged(false);\n this.pressOut.emit(event);\n };\n if (delay > 0) this.pressOutTimer = setTimeout(out, delay);\n else out();\n }\n\n private clearTimers(): void {\n // Every touchable is destroyed through here, and nearly all of them were never pressed.\n if (!this.pressInTimer && !this.longPressTimer && !this.pressOutTimer) return;\n for (const timer of [this.pressInTimer, this.longPressTimer, this.pressOutTimer]) {\n if (timer) clearTimeout(timer);\n }\n this.pressInTimer = this.longPressTimer = this.pressOutTimer = null;\n }\n}\n\n/**\n * A touchable that is a control: `Pressable`, `TouchableOpacity` and `PressBehavior`.\n *\n * The host bindings every control needs live here rather than on `TouchableBase`, which `Text`\n * extends: the state that follows `disabled`, and the Android ripple. Controls are few enough on\n * a screen to pay for a binding on every pass; texts are not.\n */\n@Directive({\n host: {\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n // Nor is it left on the node for `:disabled` to read, so this is what a stylesheet matches.\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '[nativeBackgroundAndroid]': 'rippleBackground()',\n '[nativeForegroundAndroid]': 'rippleForeground()',\n },\n})\nexport abstract class ControlBase extends TouchableBase {}\n\n/**\n * The press machine on its own, for a component that wants to be pressable rather than to\n * contain something that is.\n *\n * No selector: this is only ever a `hostDirectives` entry. A component listing it gets the whole\n * of `TouchableBase` on its own host node - the responder negotiation, the press rectangle, the\n * delays and the long-press timer - instead of wrapping a `<pressable>` and paying for a second\n * native view.\n *\n * It provides `TouchableBase`, so a primitive on the same node can `inject(TouchableBase)` and\n * read `pressed` without caring whether it landed on this or on a real `<pressable>`.\n */\n@Directive({\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => PressBehavior) }],\n})\nexport class PressBehavior extends ControlBase {\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n}\n\n/**\n * A view that responds to presses. RN's `Pressable`, with the same configuration: hit slop,\n * retention offset, press-in and press-out delays, long press, and an Android ripple.\n *\n * `pressed` is a public signal, so a template can style from it through a template reference:\n * `<pressable #p [style.opacity]=\"p.pressed() ? 0.5 : 1\">`.\n */\n@Directive({\n selector: 'pressable',\n exportAs: 'pressable',\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => Pressable) }],\n})\nexport class Pressable extends ControlBase {\n /** `Pressable.js`: a control is an accessibility element, and focusable, unless refused. */\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n}\n"]}
1
+ {"version":3,"file":"pressable.js","sourceRoot":"","sources":["../src/pressable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Press handling, built on the engine's responder system as RN's `Pressability` is.\n *\n * `onPress` is not a native event: RN synthesises it in JS from the touch primitives, with a\n * press rectangle, delays and a long-press timer around them. This is that machine, on the same\n * responder negotiation, so a button and an enclosing scroll view agree on who owns a drag.\n */\nimport {\n Directive,\n booleanAttribute,\n computed,\n forwardRef,\n input,\n numberAttribute,\n output,\n signal,\n type Signal,\n} from '@angular/core';\nimport { nativePlatform, type NativeSyntheticEvent } from '@ng-native/fabric';\nimport type { Insets, TouchEvent } from './events.ts';\nimport { optionalBoolean } from './transforms.ts';\nimport { ViewBase } from './view-base.ts';\n\n/** What a press handler receives: RN's `{nativeEvent}` shape, passed straight through. */\nexport type PressEvent = TouchEvent;\n\n/**\n * Android's ripple, drawn natively. `foreground` paints it over the content rather than behind.\n */\nexport interface AndroidRipple {\n readonly color?: string | number;\n readonly borderless?: boolean;\n readonly radius?: number;\n readonly foreground?: boolean;\n}\n\n/**\n * How far outside its own bounds a control keeps a press: RN's `DEFAULT_PRESS_RECT_OFFSETS`.\n * More room below, because a thumb rolls downwards as it lifts.\n */\nconst DEFAULT_PRESS_RETENTION: Required<Insets> = { top: 20, left: 20, right: 20, bottom: 30 };\n/** RN's `DEFAULT_LONG_PRESS_DELAY_MS`. */\nconst DEFAULT_LONG_PRESS_DELAY = 500;\n/** RN's `DEFAULT_MIN_PRESS_DURATION`: the pressed look stays at least this long on a quick tap. */\nconst DEFAULT_MIN_PRESS_DURATION = 130;\n\n/**\n * Used only until a control has been measured. RN measures the view and cancels when the touch\n * leaves its bounds plus the retention offset; before the first layout arrives there are no\n * bounds to compare against, so fall back to a small movement threshold rather than treating a\n * drag of any length as a tap.\n */\nconst PRESS_CANCEL_DISTANCE = 15;\n\nconst insets = (value: Insets | number | undefined, fallback: Required<Insets>) => {\n if (value === undefined) return fallback;\n if (typeof value === 'number') return { top: value, left: value, right: value, bottom: value };\n return {\n top: value.top ?? 0,\n left: value.left ?? 0,\n right: value.right ?? 0,\n bottom: value.bottom ?? 0,\n };\n};\n\n/** Page-space touch point, tolerating the several shapes a Fabric touch payload can take. */\nfunction touchPoint(event: NativeSyntheticEvent): { x: number; y: number } {\n const native = (event.nativeEvent ?? {}) as {\n pageX?: number;\n pageY?: number;\n touches?: { pageX?: number; pageY?: number }[];\n };\n const touch = native.touches?.[0];\n return {\n x: native.pageX ?? touch?.pageX ?? 0,\n y: native.pageY ?? touch?.pageY ?? 0,\n };\n}\n\n/** What `rippleDrawable` builds: Android's `RippleAndroid` drawable description. */\ninterface RippleDrawable {\n readonly type: 'RippleAndroid';\n readonly color: unknown;\n readonly borderless: boolean;\n readonly rippleRadius: number | undefined;\n}\n\nconst now = (): number => globalThis.performance?.now?.() ?? Date.now();\n\n/**\n * The press machine, and the base of every primitive that takes a touch.\n *\n * It declares no host bindings of its own, because `Text` extends it and a host binding runs on\n * every element that carries it, on every pass. The controls bind theirs through `ControlBase`.\n */\n@Directive()\nexport abstract class TouchableBase extends ViewBase {\n /**\n * Ignore touches entirely. Undefined until set, because React Native tells \"not passed\" from\n * \"passed false\": only a passed `disabled` wins over `aria-disabled` in what is announced.\n */\n readonly disabled = input(undefined, { transform: optionalBoolean });\n\n /**\n * How far outside the hit area a touch may wander before the press is cancelled. Native's\n * `hitSlop` grows the area a touch can start in; this grows the area it may move within.\n */\n readonly pressRetentionOffset = input<Insets | number>();\n /** Milliseconds a touch must be held before `(longPress)` fires. */\n readonly delayLongPress = input(DEFAULT_LONG_PRESS_DELAY, { transform: numberAttribute });\n /** Milliseconds between the touch landing and `(pressIn)`, so a scroll can start first. */\n readonly delayPressIn = input(0, { transform: numberAttribute });\n /** Milliseconds between the touch lifting and `(pressOut)`. */\n readonly delayPressOut = input(0, { transform: numberAttribute });\n /** The pressed state lasts at least this long, so a quick tap still shows it. */\n readonly minPressDuration = input(DEFAULT_MIN_PRESS_DURATION, { transform: numberAttribute });\n /** Whether a scrolling ancestor may take the gesture away mid-press. */\n readonly cancelable = input(true, { transform: booleanAttribute });\n /** Android: a native ripple on press. */\n readonly androidRipple = input<AndroidRipple>(undefined, { alias: 'android_ripple' });\n\n /** The touch lifted inside the press area. Not fired after a `(longPress)` that has a listener. */\n readonly press = output<PressEvent>();\n readonly pressIn = output<PressEvent>();\n readonly pressOut = output<PressEvent>();\n /**\n * The touch has been held for `delayLongPress`. With no listener there is no long press, as in\n * React Native, so a slow tap is still a `press`.\n */\n readonly longPress = output<PressEvent>();\n\n /** Whether a press is in progress, for the pressed look. */\n readonly pressed = signal(false);\n\n /**\n * Whether a pointer is over the control, which on this platform means an iPad with a trackpad\n * or a mouse. Always false on a phone, because a phone never sends a pointer event.\n *\n * Opted into by exactly the elements that opt into being measured, which is the same question\n * asked twice: is this a control, or is it a piece of text that merely inherits the machinery.\n * Registering on everything was the first attempt and put two props on every paragraph on\n * screen, which is the most numerous node in an app paying for a state a label cannot use.\n */\n readonly hovered = signal(false);\n\n /*\n * Methods rather than `computed()`s, because nearly every instance has no ripple and a computed\n * is an allocation per element whether or not it ever holds anything. The drawable is kept for as\n * long as the ripple it came from, which is the memo the computed was there to provide: a fresh\n * object on every pass would re-send the prop on every pass.\n */\n protected rippleBackground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple && !ripple.foreground ? this.drawable(ripple) : undefined;\n }\n\n protected rippleForeground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple?.foreground ? this.drawable(ripple) : undefined;\n }\n\n private drawn: { ripple: AndroidRipple; drawable: RippleDrawable } | null = null;\n\n private drawable(ripple: AndroidRipple): RippleDrawable {\n if (this.drawn?.ripple !== ripple)\n this.drawn = { ripple, drawable: this.rippleDrawable(ripple) };\n return this.drawn.drawable;\n }\n\n /**\n * The drawable description Android's `ReactDrawableHelper` reads.\n *\n * `color` goes through the engine the way every other colour prop does, and has to: the helper\n * switches on the value's runtime type and takes a number or a platform-colour map, and anything\n * else - a `'#ff0000'` written at the call site, say - falls through to `null` and the ripple\n * draws in the theme's own `colorControlHighlight` instead. Nothing is logged and nothing throws,\n * so the ripple appears and is simply the wrong colour. RN's own `TouchableNativeFeedback.Ripple`\n * calls `processColor` here for the same reason.\n */\n private rippleDrawable(ripple: AndroidRipple): RippleDrawable {\n return {\n type: 'RippleAndroid' as const,\n color: this.engine.color(ripple.color),\n borderless: ripple.borderless ?? false,\n rippleRadius: ripple.radius,\n };\n }\n\n /** Where the touch started, so a drag can be told apart from a tap. */\n private origin: { x: number; y: number } | null = null;\n /** The control's own size, from its last layout. Null until it has been measured once. */\n private size: { width: number; height: number } | null = null;\n private cancelled = false;\n private longPressed = false;\n /** How many `(longPress)` listeners there are; the long-press clock only runs with one. */\n private longPressListeners = 0;\n private pressedAt = 0;\n private pressInTimer: ReturnType<typeof setTimeout> | null = null;\n private longPressTimer: ReturnType<typeof setTimeout> | null = null;\n private pressOutTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n super();\n // output() has to be a member's own initializer for the compiler to see it, so its listeners\n // are counted here, through its public subscribe.\n const subscribe = this.longPress.subscribe.bind(this.longPress);\n this.longPress.subscribe = (callback) => {\n this.longPressListeners++;\n const subscription = subscribe(callback);\n let open = true;\n return {\n unsubscribe: () => {\n if (open) this.longPressListeners--;\n open = false;\n subscription.unsubscribe();\n },\n };\n };\n }\n\n /** Called as a press starts and ends, for a subclass that shows it natively. `Text` does. */\n protected pressedChanged(_pressed: boolean): void {}\n\n /** Whether a touch starting on this node should be claimed. `Text` narrows it. */\n protected claims(): boolean {\n return !this.pressDisabled();\n }\n\n /**\n * Whether presses are refused. `Pressable.js` gives Pressability `disabled` alone, so here\n * `aria-disabled` and `accessibilityState.disabled` change what is announced and nothing else.\n * `TouchableOpacity` and `Text` widen it.\n */\n protected pressDisabled(): boolean {\n return !!this.disabled();\n }\n\n /**\n * `TouchableOpacity.js` and `Text.js`: `disabled ?? aria-disabled ?? accessibilityState.disabled`,\n * which is the merged announced state whenever `disabled` is unset.\n */\n protected disabledByAnyState(): boolean {\n return (this.disabled() ?? this.accessibilityStateProp()?.disabled) === true;\n }\n\n /**\n * Whether the control's size should be tracked. Native only measures a view that asks, so\n * this must not be true for every `<text>`: a pressable text opts in, a label never does.\n */\n protected measures(): boolean {\n return true;\n }\n\n /**\n * Whether a touch this far from where it started is still on the control.\n *\n * Distance from the origin is the wrong question on anything large: a thumb tap on a full-width\n * button easily travels twenty points without ever leaving it, and cancelling there reads as\n * \"the button doesn't work\", intermittently and only for some people. What matters is whether\n * the finger is still within the control plus its hit slop, plus the slop RN allows.\n *\n * The touch began somewhere inside the control but we do not know where, so the bound is the\n * full extent rather than half of it. That errs towards keeping the press, which is the right\n * way to be wrong: a press that survives a drag the user meant as a scroll is a smaller sin\n * than a tap that does nothing.\n */\n private stillOnControl(dx: number, dy: number): boolean {\n if (!this.size) return Math.hypot(dx, dy) <= PRESS_CANCEL_DISTANCE;\n const slop = insets(this.hitSlop(), { top: 0, left: 0, right: 0, bottom: 0 });\n const keep = insets(this.pressRetentionOffset(), DEFAULT_PRESS_RETENTION);\n const horizontal = dx < 0 ? slop.left + keep.left : slop.right + keep.right;\n const vertical = dy < 0 ? slop.top + keep.top : slop.bottom + keep.bottom;\n return (\n Math.abs(dx) <= this.size.width + horizontal && Math.abs(dy) <= this.size.height + vertical\n );\n }\n\n /**\n * A lifecycle hook rather than `inject(DestroyRef).onDestroy`: Angular registers a hook once per\n * directive type, where the callback was a closure and a lookup for every instance - and every\n * `<text>` on screen is one.\n */\n ngOnDestroy(): void {\n this.clearTimers();\n this.stopResponding?.();\n this.stopLayout?.();\n this.stopHover?.();\n this.stopClick?.();\n }\n\n private stopResponding: (() => void) | null = null;\n private stopLayout: (() => void) | null = null;\n private stopHover: (() => void) | null = null;\n private stopClick: (() => void) | null = null;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n this.clickIfNeeded();\n }\n\n override ngOnChanges(): void {\n super.ngOnChanges();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n this.clickIfNeeded();\n }\n\n /**\n * A press with no touch: Android's `performClick()`, which is what Enter, the D-pad centre and\n * TalkBack's double-tap do to a focused view, and which reaches us as `topClick` alone.\n *\n * `Pressability.js` answers it in `onClick`: `onPress` and nothing around it, not while disabled,\n * and not for a click carrying a `pointerType`, which is the pointer event a touch already\n * pressed through. It presses only the view that was clicked: a touchable the click only bubbled\n * through stops it there, so neither it nor anything above it acts on a click meant for a\n * focusable view inside it.\n *\n * Android only. iOS sends a click only as a pointer event, and the web host binds `topClick` to\n * the DOM's own click, which a mouse press already reached through the responder.\n */\n private clickIfNeeded(): void {\n if (this.stopClick || !this.measures() || nativePlatform() !== 'android') return;\n this.stopClick = this.engine.setEventListener(this.node, 'topClick', (event) => {\n const click = event as PressEvent;\n if (!this.measures() || Object.hasOwn(click.nativeEvent ?? {}, 'pointerType')) return;\n if (click.target !== this.node) {\n click.stopPropagation();\n return;\n }\n if (this.claims()) this.press.emit(click);\n });\n }\n\n /**\n * Join the responder negotiation, once this is something a touch can press.\n *\n * Behind `measures()` for the same reason as layout and hover: a `<text>` is the commonest node\n * on screen and almost never a control, and registering every one cost a handler object, six\n * closures and a responder entry apiece for a touch it would have refused anyway.\n */\n private respondIfNeeded(): void {\n if (this.stopResponding || !this.measures()) return;\n this.stopResponding = this.engine.setResponder(this.node, {\n // Claim the gesture on touch down unless disabled. Because this goes through the\n // negotiation, an ancestor can pre-empt us in the capture pass and a nested pressable\n // wins over us in the bubble pass, neither of which raw touch listeners could express.\n onStartShouldSetResponder: () => this.claims(),\n onResponderGrant: (event) => this.onGrant(event),\n onResponderMove: (event) => this.onMove(event),\n onResponderRelease: (event) => this.onRelease(event),\n onResponderTerminate: (event) => this.onTerminate(event),\n // Yield to an enclosing scroll view when it takes over the drag, unless told not to.\n onResponderTerminationRequest: () => this.cancelable(),\n });\n }\n\n /**\n * `onLayout` is opted into by the engine as soon as something listens for it, which is the only\n * way the native side reports a view's size at all, and the reason it is only asked for once\n * `measures()` says so - a `<text>` answers that from an input, and most of them say no.\n *\n * Called from the lifecycle rather than watched by an effect. An effect per element is an\n * allocation and a scheduler entry for every pressable and every piece of text on screen, to\n * notice a change these two hooks already see.\n */\n /**\n * Hover, on the same terms and behind the same question.\n *\n * Fabric will not dispatch a pointer event to a view whose props have not asked for one, and\n * the engine writes those props when something listens - so listening is the whole opt-in. The\n * gate is `measures()`, which is not what its name is about but is the right question underneath\n * it: is this an actual control, or a piece of text that merely inherits the machinery. A label\n * says no, and two props on every paragraph on screen is not a cost worth paying for a hover\n * state a label has no use for.\n *\n * Never true on a phone, which sends no pointer events at all. This is the one thing an iPad\n * with a trackpad has that a phone does not.\n */\n private hoverIfNeeded(): void {\n if (this.stopHover || !this.measures()) return;\n const enter = this.engine.setEventListener(this.node, 'topPointerEnter', () =>\n this.hovered.set(true),\n );\n const leave = this.engine.setEventListener(this.node, 'topPointerLeave', () =>\n this.hovered.set(false),\n );\n this.stopHover = () => {\n enter();\n leave();\n };\n }\n\n private measureIfNeeded(): void {\n if (this.stopLayout || !this.measures()) return;\n this.stopLayout = this.engine.setEventListener(this.node, 'topLayout', (event) => {\n const layout = (event as NativeSyntheticEvent<{ layout?: { width: number; height: number } }>)\n .nativeEvent?.layout;\n if (layout) this.size = { width: layout.width, height: layout.height };\n });\n }\n\n private onGrant(event: PressEvent): void {\n this.origin = touchPoint(event);\n this.cancelled = false;\n this.longPressed = false;\n this.clearTimers();\n if (this.androidRipple()) {\n const { x, y } = this.origin;\n this.engine.dispatchCommand(this.node, 'hotspotUpdate', [x, y]);\n this.engine.dispatchCommand(this.node, 'setPressed', [true]);\n }\n const delay = this.delayPressIn();\n if (delay > 0) this.pressInTimer = setTimeout(() => this.activate(event), delay);\n else this.activate(event);\n }\n\n /** `pressIn`, and the long-press clock starts from here. */\n private activate(event: PressEvent): void {\n this.pressInTimer = null;\n this.pressedAt = now();\n this.pressed.set(true);\n this.pressedChanged(true);\n this.pressIn.emit(event);\n if (!this.longPressListeners) return;\n this.longPressTimer = setTimeout(() => {\n this.longPressTimer = null;\n this.longPressed = true;\n this.longPress.emit(event);\n }, this.delayLongPress());\n }\n\n private onMove(event: PressEvent): void {\n if (this.cancelled || !this.origin) return;\n const point = touchPoint(event);\n if (this.stillOnControl(point.x - this.origin.x, point.y - this.origin.y)) return;\n // The finger has wandered: this is a drag, not a tap. Give up the press but stay the\n // responder, so a scroll view underneath still gets its gesture.\n this.cancelled = true;\n this.deactivate(event);\n }\n\n private onRelease(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n // Lifted before the press-in delay ran out: RN still reports a full press.\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.activate(event);\n }\n const longPressed = this.longPressed;\n this.deactivate(event);\n if (!longPressed) this.press.emit(event);\n }\n\n private onTerminate(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n this.cancelled = true;\n this.deactivate(event);\n }\n\n /** `pressOut`, no sooner than `minPressDuration` after `pressIn` and after `delayPressOut`. */\n private deactivate(event: PressEvent): void {\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.pressInTimer = null;\n return;\n }\n if (this.longPressTimer) {\n clearTimeout(this.longPressTimer);\n this.longPressTimer = null;\n }\n if (!this.pressed()) return;\n const held = now() - this.pressedAt;\n const delay = Math.max(this.delayPressOut(), this.minPressDuration() - held);\n const out = () => {\n this.pressOutTimer = null;\n this.pressed.set(false);\n this.pressedChanged(false);\n this.pressOut.emit(event);\n };\n if (delay > 0) this.pressOutTimer = setTimeout(out, delay);\n else out();\n }\n\n private clearTimers(): void {\n // Every touchable is destroyed through here, and nearly all of them were never pressed.\n if (!this.pressInTimer && !this.longPressTimer && !this.pressOutTimer) return;\n for (const timer of [this.pressInTimer, this.longPressTimer, this.pressOutTimer]) {\n if (timer) clearTimeout(timer);\n }\n this.pressInTimer = this.longPressTimer = this.pressOutTimer = null;\n }\n}\n\n/**\n * A touchable that is a control: `Pressable`, `TouchableOpacity` and `PressBehavior`.\n *\n * The host bindings every control needs live here rather than on `TouchableBase`, which `Text`\n * extends: the state that follows `disabled`, and the Android ripple. Controls are few enough on\n * a screen to pay for a binding on every pass; texts are not.\n */\n@Directive({\n host: {\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n // Nor is it left on the node for `:disabled` to read, so this is what a stylesheet matches.\n '[attr.data-disabled]': \"pressDisabled() ? '' : null\",\n '[nativeBackgroundAndroid]': 'rippleBackground()',\n '[nativeForegroundAndroid]': 'rippleForeground()',\n },\n})\nexport abstract class ControlBase extends TouchableBase {}\n\n/**\n * The press machine on its own, for a component that wants to be pressable rather than to\n * contain something that is.\n *\n * No selector: this is only ever a `hostDirectives` entry. A component listing it gets the whole\n * of `TouchableBase` on its own host node - the responder negotiation, the press rectangle, the\n * delays and the long-press timer - instead of wrapping a `<pressable>` and paying for a second\n * native view.\n *\n * It provides `TouchableBase`, so a primitive on the same node can `inject(TouchableBase)` and\n * read `pressed` without caring whether it landed on this or on a real `<pressable>`.\n */\n@Directive({\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => PressBehavior) }],\n})\nexport class PressBehavior extends ControlBase {\n /** The conditions the composing component gave, any of which disables the control. */\n private readonly conditions = signal<readonly Signal<boolean>[]>([]);\n private readonly held = computed(() => this.conditions().some((condition) => condition()));\n\n /**\n * Disable the control while `condition` is true, from the component that composes this: a\n * button that is loading, which its caller's `disabled` knows nothing of. Either one disables\n * it, as `disabled={loading || disabled}` does on React Native's `Pressable`: presses are\n * refused, a stylesheet sees `[data-disabled]`, and a screen reader is told.\n *\n * constructor() {\n * inject(PressBehavior).disableWhile(this.loading);\n * }\n */\n disableWhile(condition: Signal<boolean>): void {\n this.conditions.update((conditions) => [...conditions, condition]);\n }\n\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override pressDisabled(): boolean {\n return this.held() || super.pressDisabled();\n }\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.held() ? true : this.disabled();\n }\n}\n\n/**\n * A view that responds to presses. RN's `Pressable`, with the same configuration: hit slop,\n * retention offset, press-in and press-out delays, long press, and an Android ripple.\n *\n * `pressed` is a public signal, so a template can style from it through a template reference:\n * `<pressable #p [style.opacity]=\"p.pressed() ? 0.5 : 1\">`.\n */\n@Directive({\n selector: 'pressable',\n exportAs: 'pressable',\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => Pressable) }],\n})\nexport class Pressable extends ControlBase {\n /** `Pressable.js`: a control is an accessibility element, and focusable, unless refused. */\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n}\n"]}
@@ -1,19 +1,11 @@
1
- import type { SharedValue, WorkletScrollSpec, WorkletStyleSpec } from './worklets.ts';
1
+ import type { MutableValue, WorkletScrollSpec, WorkletStyleSpec } from './worklets.ts';
2
2
  import * as i0 from "@angular/core";
3
3
  export { workletScroll, workletStyle, type SharedValue, type WorkletScrollSpec, type WorkletStyleSpec, } from './worklets.ts';
4
- /** Reanimated's public `SharedValue` surface, which code outside a worklet reads and writes. */
5
- interface PlainSharedValue<T> extends SharedValue<T> {
6
- get(): T;
7
- set(value: T | ((value: T) => T)): void;
8
- modify(modifier?: (value: T) => T): void;
9
- addListener(id: number, listener: (value: T) => void): void;
10
- removeListener(id: number): void;
11
- }
12
4
  /**
13
5
  * A shared value as a plain holder, with no second runtime to share it with. Every write reaches
14
6
  * the listeners added with `addListener`.
15
7
  */
16
- export declare function sharedValue<T>(initial: T): PlainSharedValue<T>;
8
+ export declare function sharedValue<T>(initial: T): MutableValue<T>;
17
9
  export declare class WorkletStyle {
18
10
  readonly workletStyle: import("@angular/core").InputSignal<WorkletStyleSpec>;
19
11
  static ɵfac: i0.ɵɵFactoryDeclaration<WorkletStyle, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"reanimated-web.js","sourceRoot":"","sources":["../src/reanimated-web.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;;AAGjD,OAAO,EACL,aAAa,EACb,YAAY,GAIb,MAAM,eAAe,CAAC;AAWvB;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAI,OAAU;IACvC,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,MAAM,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;IACxD,MAAM,KAAK,GAAG,CAAC,IAAO,EAAE,EAAE;QACxB,OAAO,GAAG,IAAI,CAAC;QACf,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC;IACF,OAAO;QACL,IAAI,KAAK;YACP,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI;YACZ,KAAK,CAAC,IAAI,CAAC,CAAC;QACd,CAAC;QACD,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO;QAClB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5F,MAAM,EAAE,CAAC,QAAQ,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjE,WAAW,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC;QAC/D,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC;AAGD,MAAM,OAAO,YAAY;IACd,YAAY,GAAG,KAAK,CAAC,QAAQ;qFAAoB,CAAC;uGADhD,YAAY;2FAAZ,YAAY;;2FAAZ,YAAY;kBADxB,SAAS;mBAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE;;AAMzC,MAAM,OAAO,aAAa;IACf,aAAa,GAAG,KAAK,CAAC,QAAQ;sFAAqB,CAAC;uGADlD,aAAa;2FAAb,aAAa;;2FAAb,aAAa;kBADzB,SAAS;mBAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE","sourcesContent":["/**\n * `reanimated.ts`, for a browser build.\n *\n * A web bundler resolves `@ng-native/components/reanimated` here, through the `browser` condition\n * in this package's `exports`; Metro, on a device, never sets that condition and gets the native\n * file. A browser has no UI-thread runtime to run a worklet on, so everything here is inert: the\n * names are the same, a template that binds `[workletStyle]` or `[workletScroll]` still renders,\n * and the directives do nothing.\n */\nimport { Directive, input } from '@angular/core';\nimport type { SharedValue, WorkletScrollSpec, WorkletStyleSpec } from './worklets.ts';\n\nexport {\n workletScroll,\n workletStyle,\n type SharedValue,\n type WorkletScrollSpec,\n type WorkletStyleSpec,\n} from './worklets.ts';\n\n/** Reanimated's public `SharedValue` surface, which code outside a worklet reads and writes. */\ninterface PlainSharedValue<T> extends SharedValue<T> {\n get(): T;\n set(value: T | ((value: T) => T)): void;\n modify(modifier?: (value: T) => T): void;\n addListener(id: number, listener: (value: T) => void): void;\n removeListener(id: number): void;\n}\n\n/**\n * A shared value as a plain holder, with no second runtime to share it with. Every write reaches\n * the listeners added with `addListener`.\n */\nexport function sharedValue<T>(initial: T): PlainSharedValue<T> {\n let current = initial;\n const listeners = new Map<number, (value: T) => void>();\n const write = (next: T) => {\n current = next;\n for (const listener of listeners.values()) listener(next);\n };\n return {\n get value() {\n return current;\n },\n set value(next) {\n write(next);\n },\n get: () => current,\n set: (next) => write(typeof next === 'function' ? (next as (value: T) => T)(current) : next),\n modify: (modifier = (value) => value) => write(modifier(current)),\n addListener: (id, listener) => void listeners.set(id, listener),\n removeListener: (id) => void listeners.delete(id),\n };\n}\n\n@Directive({ selector: '[workletStyle]' })\nexport class WorkletStyle {\n readonly workletStyle = input.required<WorkletStyleSpec>();\n}\n\n@Directive({ selector: '[workletScroll]' })\nexport class WorkletScroll {\n readonly workletScroll = input.required<WorkletScrollSpec>();\n}\n"]}
1
+ {"version":3,"file":"reanimated-web.js","sourceRoot":"","sources":["../src/reanimated-web.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;;AAGjD,OAAO,EACL,aAAa,EACb,YAAY,GAIb,MAAM,eAAe,CAAC;AAEvB;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAI,OAAU;IACvC,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,MAAM,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;IACxD,MAAM,KAAK,GAAG,CAAC,IAAO,EAAE,EAAE;QACxB,OAAO,GAAG,IAAI,CAAC;QACf,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC;IACF,OAAO;QACL,IAAI,KAAK;YACP,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI;YACZ,KAAK,CAAC,IAAI,CAAC,CAAC;QACd,CAAC;QACD,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO;QAClB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5F,MAAM,EAAE,CAAC,QAAQ,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjE,WAAW,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC;QAC/D,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC;AAGD,MAAM,OAAO,YAAY;IACd,YAAY,GAAG,KAAK,CAAC,QAAQ;qFAAoB,CAAC;uGADhD,YAAY;2FAAZ,YAAY;;2FAAZ,YAAY;kBADxB,SAAS;mBAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE;;AAMzC,MAAM,OAAO,aAAa;IACf,aAAa,GAAG,KAAK,CAAC,QAAQ;sFAAqB,CAAC;uGADlD,aAAa;2FAAb,aAAa;;2FAAb,aAAa;kBADzB,SAAS;mBAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE","sourcesContent":["/**\n * `reanimated.ts`, for a browser build.\n *\n * A web bundler resolves `@ng-native/components/reanimated` here, through the `browser` condition\n * in this package's `exports`; Metro, on a device, never sets that condition and gets the native\n * file. A browser has no UI-thread runtime to run a worklet on, so everything here is inert: the\n * names are the same, a template that binds `[workletStyle]` or `[workletScroll]` still renders,\n * and the directives do nothing.\n */\nimport { Directive, input } from '@angular/core';\nimport type { MutableValue, WorkletScrollSpec, WorkletStyleSpec } from './worklets.ts';\n\nexport {\n workletScroll,\n workletStyle,\n type SharedValue,\n type WorkletScrollSpec,\n type WorkletStyleSpec,\n} from './worklets.ts';\n\n/**\n * A shared value as a plain holder, with no second runtime to share it with. Every write reaches\n * the listeners added with `addListener`.\n */\nexport function sharedValue<T>(initial: T): MutableValue<T> {\n let current = initial;\n const listeners = new Map<number, (value: T) => void>();\n const write = (next: T) => {\n current = next;\n for (const listener of listeners.values()) listener(next);\n };\n return {\n get value() {\n return current;\n },\n set value(next) {\n write(next);\n },\n get: () => current,\n set: (next) => write(typeof next === 'function' ? (next as (value: T) => T)(current) : next),\n modify: (modifier = (value) => value) => write(modifier(current)),\n addListener: (id, listener) => void listeners.set(id, listener),\n removeListener: (id) => void listeners.delete(id),\n };\n}\n\n@Directive({ selector: '[workletStyle]' })\nexport class WorkletStyle {\n readonly workletStyle = input.required<WorkletStyleSpec>();\n}\n\n@Directive({ selector: '[workletScroll]' })\nexport class WorkletScroll {\n readonly workletScroll = input.required<WorkletScrollSpec>();\n}\n"]}
@@ -1,14 +1,14 @@
1
- import { type SharedValue as Mutable } from 'react-native-reanimated';
2
1
  import { WorkletScrollBase } from './worklet-scroll.ts';
3
2
  import { WorkletStyleBase } from './worklet-style.ts';
3
+ import { type MutableValue } from './worklets.ts';
4
4
  import * as i0 from "@angular/core";
5
5
  export { workletScroll, workletStyle, type SharedValue, type WorkletScrollSpec, type WorkletStyleSpec, } from './worklets.ts';
6
6
  /**
7
7
  * A value both runtimes can see. Reanimated's own `useSharedValue` is this plus a React ref, and
8
- * the ref is the half that does not apply here. Typed as Reanimated's own, so it goes to
9
- * `cancelAnimation` and the rest of the library as one of theirs would.
8
+ * the ref is the half that does not apply here. Typed with the shape of Reanimated's own, so it
9
+ * goes to `cancelAnimation` and the rest of the library as one of theirs would.
10
10
  */
11
- export declare function sharedValue<T>(initial: T): Mutable<T>;
11
+ export declare function sharedValue<T>(initial: T): MutableValue<T>;
12
12
  export declare class WorkletStyle extends WorkletStyleBase {
13
13
  static ɵfac: i0.ɵɵFactoryDeclaration<WorkletStyle, never>;
14
14
  static ɵdir: i0.ɵɵDirectiveDeclaration<WorkletStyle, "[workletStyle]", never, {}, {}, never, never, true, never>;
@@ -31,7 +31,7 @@
31
31
  * them, and re-exporting them here would only add a name to keep in step.
32
32
  */
33
33
  import { Directive } from '@angular/core';
34
- import { makeMutable, startMapper, stopMapper, } from 'react-native-reanimated';
34
+ import { makeMutable, startMapper, stopMapper } from 'react-native-reanimated';
35
35
  import { WorkletScrollBase } from "./worklet-scroll.js";
36
36
  import { WorkletStyleBase } from "./worklet-style.js";
37
37
  import { WORKLETS } from "./worklets.js";
@@ -50,8 +50,8 @@ const { updateProps } = require('react-native-reanimated/src/updateProps/index.t
50
50
  export { workletScroll, workletStyle, } from "./worklets.js";
51
51
  /**
52
52
  * A value both runtimes can see. Reanimated's own `useSharedValue` is this plus a React ref, and
53
- * the ref is the half that does not apply here. Typed as Reanimated's own, so it goes to
54
- * `cancelAnimation` and the rest of the library as one of theirs would.
53
+ * the ref is the half that does not apply here. Typed with the shape of Reanimated's own, so it
54
+ * goes to `cancelAnimation` and the rest of the library as one of theirs would.
55
55
  */
56
56
  export function sharedValue(initial) {
57
57
  return makeMutable(initial);
@@ -1 +1 @@
1
- {"version":3,"file":"reanimated.js","sourceRoot":"","sources":["../src/reanimated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EACL,WAAW,EACX,WAAW,EACX,UAAU,GAEX,MAAM,yBAAyB,CAAC;AAcjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAuB,MAAM,eAAe,CAAC;;AAf9D;;;;;;;;;GASG;AACH,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,kDAAkD,CAEjF,CAAC;AAKF,OAAO,EACL,aAAa,EACb,YAAY,GAIb,MAAM,eAAe,CAAC;AAEvB;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAI,OAAU;IACvC,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,OAAO,GAAmB;IAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACtB,yFAAyF;QACzF,2FAA2F;QAC3F,2DAA2D;QAC3D,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;QAC3F,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAClC,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;YAC1B,SAAS,CAAC;YACV,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC,EAAE,MAAmB,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACjC,0FAA0F;QAC1F,0FAA0F;QAC1F,MAAM,EAAE,GAAG,oBAAoB,CAC7B,CAAC,KAAY,EAAE,EAAE;YACf,SAAS,CAAC;YACV,OAAO,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAC5B,CAAC,EACD,UAAU,EACV,MAAM,CAAC,GAAG,CACX,CAAC;QACF,OAAO,GAAG,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,GACpD,OAAO,CAAC,qCAAqC,CAO5C,CAAC;AAMJ,MAAM,OAAO,YAAa,SAAQ,gBAAgB;uGAArC,YAAY;2FAAZ,YAAY,6DAFZ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;;2FAE1C,YAAY;kBAJxB,SAAS;mBAAC;oBACT,QAAQ,EAAE,gBAAgB;oBAC1B,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBACtD;;AAOD,MAAM,OAAO,aAAc,SAAQ,iBAAiB;uGAAvC,aAAa;2FAAb,aAAa,8DAFb,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;;2FAE1C,aAAa;kBAJzB,SAAS;mBAAC;oBACT,QAAQ,EAAE,iBAAiB;oBAC3B,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBACtD","sourcesContent":["/**\n * Reanimated, without React: a style computed on the UI thread, bound to one of our nodes.\n *\n * ```ts\n * import { WorkletStyle, sharedValue, workletStyle } from '@ng-native/components/reanimated';\n *\n * protected readonly offset = sharedValue(0);\n * protected readonly slide = workletStyle([this.offset], (offset) => {\n * 'worklet';\n * return { transform: [{ translateX: offset.value }] };\n * });\n * ```\n * ```html\n * <view [workletStyle]=\"slide\">\n * ```\n *\n * Deliberately outside the barrel: everything here reaches React Native's\n * Flow source, which Node cannot parse, and the rest of the package has to stay loadable in the\n * test suite.\n *\n * What makes this work at all is that Reanimated addresses a view by its **shadow node**, not by a\n * React instance. `getShadowNodeWrapperFromRef` digs one out of a fiber; our engine has held the\n * same object since it created the node, so there is nothing to dig for. `startMapper` and\n * `makeMutable` are public, and the whole React half of `useAnimatedStyle` - refs, effects, the\n * animated component wrapper - is what an Angular directive replaces.\n *\n * An app installs `react-native-reanimated` and `react-native-worklets` itself, and gets the\n * worklet Babel plugin from `babel-preset-expo`, which adds it as soon as the package is present.\n * Everything else an animation needs - `withTiming`, `withSpring`, `interpolate`, `Easing` - is\n * imported from `react-native-reanimated` directly: they are plain functions with no React in\n * them, and re-exporting them here would only add a name to keep in step.\n */\nimport { Directive } from '@angular/core';\nimport {\n makeMutable,\n startMapper,\n stopMapper,\n type SharedValue as Mutable,\n} from 'react-native-reanimated';\n/**\n * `updateProps` is what every animated style in Reanimated goes through, and there is no exported\n * equivalent. It is a worklet, so it is called from ours rather than from here.\n *\n * Two things about the import. It goes through `src/` because that is where the package's own\n * `react-native` field points and Metro prefers that field: the built `lib/` copy would be a\n * second Reanimated in the bundle, with module state of its own. And it is a `require`, so that\n * these sources stay out of our type-checking program, where they fail against settings they were\n * never written for.\n */\nconst { updateProps } = require('react-native-reanimated/src/updateProps/index.ts') as {\n updateProps(descriptors: object, updates: Record<string, unknown>): void;\n};\nimport { WorkletScrollBase } from './worklet-scroll.ts';\nimport { WorkletStyleBase } from './worklet-style.ts';\nimport { WORKLETS, type WorkletBackend } from './worklets.ts';\n\nexport {\n workletScroll,\n workletStyle,\n type SharedValue,\n type WorkletScrollSpec,\n type WorkletStyleSpec,\n} from './worklets.ts';\n\n/**\n * A value both runtimes can see. Reanimated's own `useSharedValue` is this plus a React ref, and\n * the ref is the half that does not apply here. Typed as Reanimated's own, so it goes to\n * `cancelAnimation` and the rest of the library as one of theirs would.\n */\nexport function sharedValue<T>(initial: T): Mutable<T> {\n return makeMutable(initial);\n}\n\nconst backend: WorkletBackend = {\n bind: (target, style) => {\n // The shape `updateProps` takes: a `{ value }` holder of descriptors, so that the set of\n // views a style drives can change without the worklet being rebuilt. Ours never does - one\n // directive drives one node - so a plain object is enough.\n const descriptors = { value: [{ tag: target.tag, shadowNodeWrapper: target.shadowNode }] };\n const { values, updater } = style;\n const id = startMapper(() => {\n 'worklet';\n updateProps(descriptors, updater(...values));\n }, values as unknown[]);\n return () => stopMapper(id);\n },\n\n scroll: (target, spec) => {\n const { values, handler } = spec;\n // The same registration a gesture uses, on the name React Native's scroll views emit. The\n // event still reaches our own listeners: Reanimated observes it rather than consuming it.\n const id = registerEventHandler(\n (event: never) => {\n 'worklet';\n handler(event, ...values);\n },\n 'onScroll',\n target.tag,\n );\n return () => unregisterEventHandler(id);\n },\n};\n\n/**\n * Not public, and the same call Reanimated's own `WorkletEventHandler` makes. Reached through\n * `src/` for the reason `updateProps` is, and required rather than imported so that those sources\n * stay out of our type-checking program.\n */\nconst { registerEventHandler, unregisterEventHandler } =\n require('react-native-reanimated/src/core.ts') as {\n registerEventHandler(\n worklet: (event: never) => void,\n eventName: string,\n emitterReactTag: number,\n ): number;\n unregisterEventHandler(id: number): void;\n };\n\n@Directive({\n selector: '[workletStyle]',\n providers: [{ provide: WORKLETS, useValue: backend }],\n})\nexport class WorkletStyle extends WorkletStyleBase {}\n\n@Directive({\n selector: '[workletScroll]',\n providers: [{ provide: WORKLETS, useValue: backend }],\n})\nexport class WorkletScroll extends WorkletScrollBase {}\n"]}
1
+ {"version":3,"file":"reanimated.js","sourceRoot":"","sources":["../src/reanimated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAc/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAA0C,MAAM,eAAe,CAAC;;AAfjF;;;;;;;;;GASG;AACH,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,kDAAkD,CAEjF,CAAC;AAKF,OAAO,EACL,aAAa,EACb,YAAY,GAIb,MAAM,eAAe,CAAC;AAEvB;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAI,OAAU;IACvC,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,OAAO,GAAmB;IAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACtB,yFAAyF;QACzF,2FAA2F;QAC3F,2DAA2D;QAC3D,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;QAC3F,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAClC,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;YAC1B,SAAS,CAAC;YACV,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC,EAAE,MAAmB,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACjC,0FAA0F;QAC1F,0FAA0F;QAC1F,MAAM,EAAE,GAAG,oBAAoB,CAC7B,CAAC,KAAY,EAAE,EAAE;YACf,SAAS,CAAC;YACV,OAAO,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAC5B,CAAC,EACD,UAAU,EACV,MAAM,CAAC,GAAG,CACX,CAAC;QACF,OAAO,GAAG,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,GACpD,OAAO,CAAC,qCAAqC,CAO5C,CAAC;AAMJ,MAAM,OAAO,YAAa,SAAQ,gBAAgB;uGAArC,YAAY;2FAAZ,YAAY,6DAFZ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;;2FAE1C,YAAY;kBAJxB,SAAS;mBAAC;oBACT,QAAQ,EAAE,gBAAgB;oBAC1B,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBACtD;;AAOD,MAAM,OAAO,aAAc,SAAQ,iBAAiB;uGAAvC,aAAa;2FAAb,aAAa,8DAFb,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;;2FAE1C,aAAa;kBAJzB,SAAS;mBAAC;oBACT,QAAQ,EAAE,iBAAiB;oBAC3B,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBACtD","sourcesContent":["/**\n * Reanimated, without React: a style computed on the UI thread, bound to one of our nodes.\n *\n * ```ts\n * import { WorkletStyle, sharedValue, workletStyle } from '@ng-native/components/reanimated';\n *\n * protected readonly offset = sharedValue(0);\n * protected readonly slide = workletStyle([this.offset], (offset) => {\n * 'worklet';\n * return { transform: [{ translateX: offset.value }] };\n * });\n * ```\n * ```html\n * <view [workletStyle]=\"slide\">\n * ```\n *\n * Deliberately outside the barrel: everything here reaches React Native's\n * Flow source, which Node cannot parse, and the rest of the package has to stay loadable in the\n * test suite.\n *\n * What makes this work at all is that Reanimated addresses a view by its **shadow node**, not by a\n * React instance. `getShadowNodeWrapperFromRef` digs one out of a fiber; our engine has held the\n * same object since it created the node, so there is nothing to dig for. `startMapper` and\n * `makeMutable` are public, and the whole React half of `useAnimatedStyle` - refs, effects, the\n * animated component wrapper - is what an Angular directive replaces.\n *\n * An app installs `react-native-reanimated` and `react-native-worklets` itself, and gets the\n * worklet Babel plugin from `babel-preset-expo`, which adds it as soon as the package is present.\n * Everything else an animation needs - `withTiming`, `withSpring`, `interpolate`, `Easing` - is\n * imported from `react-native-reanimated` directly: they are plain functions with no React in\n * them, and re-exporting them here would only add a name to keep in step.\n */\nimport { Directive } from '@angular/core';\nimport { makeMutable, startMapper, stopMapper } from 'react-native-reanimated';\n/**\n * `updateProps` is what every animated style in Reanimated goes through, and there is no exported\n * equivalent. It is a worklet, so it is called from ours rather than from here.\n *\n * Two things about the import. It goes through `src/` because that is where the package's own\n * `react-native` field points and Metro prefers that field: the built `lib/` copy would be a\n * second Reanimated in the bundle, with module state of its own. And it is a `require`, so that\n * these sources stay out of our type-checking program, where they fail against settings they were\n * never written for.\n */\nconst { updateProps } = require('react-native-reanimated/src/updateProps/index.ts') as {\n updateProps(descriptors: object, updates: Record<string, unknown>): void;\n};\nimport { WorkletScrollBase } from './worklet-scroll.ts';\nimport { WorkletStyleBase } from './worklet-style.ts';\nimport { WORKLETS, type MutableValue, type WorkletBackend } from './worklets.ts';\n\nexport {\n workletScroll,\n workletStyle,\n type SharedValue,\n type WorkletScrollSpec,\n type WorkletStyleSpec,\n} from './worklets.ts';\n\n/**\n * A value both runtimes can see. Reanimated's own `useSharedValue` is this plus a React ref, and\n * the ref is the half that does not apply here. Typed with the shape of Reanimated's own, so it\n * goes to `cancelAnimation` and the rest of the library as one of theirs would.\n */\nexport function sharedValue<T>(initial: T): MutableValue<T> {\n return makeMutable(initial);\n}\n\nconst backend: WorkletBackend = {\n bind: (target, style) => {\n // The shape `updateProps` takes: a `{ value }` holder of descriptors, so that the set of\n // views a style drives can change without the worklet being rebuilt. Ours never does - one\n // directive drives one node - so a plain object is enough.\n const descriptors = { value: [{ tag: target.tag, shadowNodeWrapper: target.shadowNode }] };\n const { values, updater } = style;\n const id = startMapper(() => {\n 'worklet';\n updateProps(descriptors, updater(...values));\n }, values as unknown[]);\n return () => stopMapper(id);\n },\n\n scroll: (target, spec) => {\n const { values, handler } = spec;\n // The same registration a gesture uses, on the name React Native's scroll views emit. The\n // event still reaches our own listeners: Reanimated observes it rather than consuming it.\n const id = registerEventHandler(\n (event: never) => {\n 'worklet';\n handler(event, ...values);\n },\n 'onScroll',\n target.tag,\n );\n return () => unregisterEventHandler(id);\n },\n};\n\n/**\n * Not public, and the same call Reanimated's own `WorkletEventHandler` makes. Reached through\n * `src/` for the reason `updateProps` is, and required rather than imported so that those sources\n * stay out of our type-checking program.\n */\nconst { registerEventHandler, unregisterEventHandler } =\n require('react-native-reanimated/src/core.ts') as {\n registerEventHandler(\n worklet: (event: never) => void,\n eventName: string,\n emitterReactTag: number,\n ): number;\n unregisterEventHandler(id: number): void;\n };\n\n@Directive({\n selector: '[workletStyle]',\n providers: [{ provide: WORKLETS, useValue: backend }],\n})\nexport class WorkletStyle extends WorkletStyleBase {}\n\n@Directive({\n selector: '[workletScroll]',\n providers: [{ provide: WORKLETS, useValue: backend }],\n})\nexport class WorkletScroll extends WorkletScrollBase {}\n"]}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `react-native-gesture-handler` where there is no native recogniser: a browser build and a test,
3
+ * which resolve the library here (`ngNativeWeb()` and `@ng-native/testing`). Nothing is recognised.
4
+ *
5
+ * `Gesture.Pan()`, `Gesture.Tap()`, `Gesture.Simultaneous(...)` and every other builder returns a
6
+ * gesture that takes any configuration call, `.minDistance(10).onUpdate(...)`, and returns itself,
7
+ * so a component builds its gestures exactly as it does on a device. The callbacks it was
8
+ * given are kept on `callbacks`, by name, for a test that wants to call one. `State` and
9
+ * `Directions` are the library's own numbers.
10
+ */
11
+ /** The configuration and callback calls gestures take, as far as a test types them. */
12
+ type GestureMethod = 'onBegin' | 'onStart' | 'onUpdate' | 'onChange' | 'onEnd' | 'onFinalize' | 'onTouchesDown' | 'onTouchesMove' | 'onTouchesUp' | 'onTouchesCancelled' | 'enabled' | 'runOnJS' | 'minDistance' | 'minPointers' | 'maxPointers' | 'numberOfTaps' | 'minDuration' | 'maxDuration' | 'direction' | 'activeOffsetX' | 'activeOffsetY' | 'failOffsetX' | 'failOffsetY' | 'hitSlop' | 'shouldCancelWhenOutside' | 'manualActivation' | 'simultaneousWithExternalGesture' | 'requireExternalGestureToFail' | 'blocksExternalGesture' | 'withRef' | 'withTestId';
13
+ /**
14
+ * A gesture built in a test: every configuration call returns it, and callbacks are kept. `kind`
15
+ * is the builder that made it, `Pan` or `Race`, and `gestures` what a composed one was made of.
16
+ */
17
+ export type StandInGesture = {
18
+ readonly kind: string;
19
+ readonly gestures: readonly StandInGesture[];
20
+ readonly callbacks: Record<string, (...args: never[]) => unknown>;
21
+ } & {
22
+ readonly [M in GestureMethod]: (...args: readonly unknown[]) => StandInGesture;
23
+ };
24
+ type Builder = 'Pan' | 'Tap' | 'LongPress' | 'Pinch' | 'Rotation' | 'Fling' | 'Hover' | 'Manual' | 'Native' | 'ForceTouch' | 'Race' | 'Simultaneous' | 'Exclusive';
25
+ export declare const Gesture: Readonly<Record<Builder, (...gestures: readonly unknown[]) => StandInGesture>>;
26
+ export declare const State: {
27
+ readonly UNDETERMINED: 0;
28
+ readonly FAILED: 1;
29
+ readonly BEGAN: 2;
30
+ readonly CANCELLED: 3;
31
+ readonly ACTIVE: 4;
32
+ readonly END: 5;
33
+ };
34
+ export declare const Directions: {
35
+ readonly RIGHT: 1;
36
+ readonly LEFT: 2;
37
+ readonly UP: 4;
38
+ readonly DOWN: 8;
39
+ };
40
+ export {};