@ng-native/components 0.0.1 → 0.1.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.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -1
  3. package/dist/activity-indicator.d.ts +41 -0
  4. package/dist/activity-indicator.js +66 -0
  5. package/dist/activity-indicator.js.map +1 -0
  6. package/dist/animated-style.d.ts +31 -0
  7. package/dist/animated-style.js +102 -0
  8. package/dist/animated-style.js.map +1 -0
  9. package/dist/animated.d.ts +125 -0
  10. package/dist/animated.js +538 -0
  11. package/dist/animated.js.map +1 -0
  12. package/dist/animation.d.ts +40 -0
  13. package/dist/animation.js +20 -0
  14. package/dist/animation.js.map +1 -0
  15. package/dist/animations-web.d.ts +8 -0
  16. package/dist/animations-web.js +31 -0
  17. package/dist/animations-web.js.map +1 -0
  18. package/dist/animations.d.ts +7 -0
  19. package/dist/animations.js +58 -0
  20. package/dist/animations.js.map +1 -0
  21. package/dist/controlled-model.d.ts +33 -0
  22. package/dist/controlled-model.js +47 -0
  23. package/dist/controlled-model.js.map +1 -0
  24. package/dist/easing.d.ts +21 -0
  25. package/dist/easing.js +50 -0
  26. package/dist/easing.js.map +1 -0
  27. package/dist/events.d.ts +169 -0
  28. package/dist/events.js +2 -0
  29. package/dist/events.js.map +1 -0
  30. package/dist/gesture-backend.d.ts +26 -0
  31. package/dist/gesture-backend.js +14 -0
  32. package/dist/gesture-backend.js.map +1 -0
  33. package/dist/gesture-dispatch.d.ts +67 -0
  34. package/dist/gesture-dispatch.js +106 -0
  35. package/dist/gesture-dispatch.js.map +1 -0
  36. package/dist/gestures.d.ts +23 -0
  37. package/dist/gestures.js +164 -0
  38. package/dist/gestures.js.map +1 -0
  39. package/dist/height-index.d.ts +31 -0
  40. package/dist/height-index.js +80 -0
  41. package/dist/height-index.js.map +1 -0
  42. package/dist/image-background.d.ts +32 -0
  43. package/dist/image-background.js +80 -0
  44. package/dist/image-background.js.map +1 -0
  45. package/dist/image.d.ts +79 -0
  46. package/dist/image.js +155 -0
  47. package/dist/image.js.map +1 -0
  48. package/dist/index.d.ts +38 -0
  49. package/dist/index.js +39 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/input-accessory-view.d.ts +16 -0
  52. package/dist/input-accessory-view.js +29 -0
  53. package/dist/input-accessory-view.js.map +1 -0
  54. package/dist/keyboard-avoiding-view.d.ts +79 -0
  55. package/dist/keyboard-avoiding-view.js +172 -0
  56. package/dist/keyboard-avoiding-view.js.map +1 -0
  57. package/dist/keyboard-dock.d.ts +126 -0
  58. package/dist/keyboard-dock.js +327 -0
  59. package/dist/keyboard-dock.js.map +1 -0
  60. package/dist/keyboard-taps.d.ts +12 -0
  61. package/dist/keyboard-taps.js +51 -0
  62. package/dist/keyboard-taps.js.map +1 -0
  63. package/dist/modal.d.ts +56 -0
  64. package/dist/modal.js +102 -0
  65. package/dist/modal.js.map +1 -0
  66. package/dist/native-gesture.d.ts +21 -0
  67. package/dist/native-gesture.js +56 -0
  68. package/dist/native-gesture.js.map +1 -0
  69. package/dist/native-ref.d.ts +7 -0
  70. package/dist/native-ref.js +13 -0
  71. package/dist/native-ref.js.map +1 -0
  72. package/dist/pressable.d.ts +220 -0
  73. package/dist/pressable.js +484 -0
  74. package/dist/pressable.js.map +1 -0
  75. package/dist/reanimated.d.ts +19 -0
  76. package/dist/reanimated.js +111 -0
  77. package/dist/reanimated.js.map +1 -0
  78. package/dist/refresh-control.d.ts +50 -0
  79. package/dist/refresh-control.js +103 -0
  80. package/dist/refresh-control.js.map +1 -0
  81. package/dist/safe-area-provider.d.ts +11 -0
  82. package/dist/safe-area-provider.js +70 -0
  83. package/dist/safe-area-provider.js.map +1 -0
  84. package/dist/safe-area-view.d.ts +22 -0
  85. package/dist/safe-area-view.js +77 -0
  86. package/dist/safe-area-view.js.map +1 -0
  87. package/dist/safe-area.d.ts +12 -0
  88. package/dist/safe-area.js +27 -0
  89. package/dist/safe-area.js.map +1 -0
  90. package/dist/scroll-view-props.d.ts +89 -0
  91. package/dist/scroll-view-props.js +153 -0
  92. package/dist/scroll-view-props.js.map +1 -0
  93. package/dist/scroll-view.d.ts +95 -0
  94. package/dist/scroll-view.js +181 -0
  95. package/dist/scroll-view.js.map +1 -0
  96. package/dist/section-list.d.ts +146 -0
  97. package/dist/section-list.js +300 -0
  98. package/dist/section-list.js.map +1 -0
  99. package/dist/sticky-headers.d.ts +41 -0
  100. package/dist/sticky-headers.js +118 -0
  101. package/dist/sticky-headers.js.map +1 -0
  102. package/dist/swipe-refresh-layout.d.ts +51 -0
  103. package/dist/swipe-refresh-layout.js +162 -0
  104. package/dist/swipe-refresh-layout.js.map +1 -0
  105. package/dist/switch.d.ts +54 -0
  106. package/dist/switch.js +110 -0
  107. package/dist/switch.js.map +1 -0
  108. package/dist/template-slot.d.ts +18 -0
  109. package/dist/template-slot.js +30 -0
  110. package/dist/template-slot.js.map +1 -0
  111. package/dist/text-input.d.ts +168 -0
  112. package/dist/text-input.js +312 -0
  113. package/dist/text-input.js.map +1 -0
  114. package/dist/text.d.ts +70 -0
  115. package/dist/text.js +111 -0
  116. package/dist/text.js.map +1 -0
  117. package/dist/touchable-opacity.d.ts +36 -0
  118. package/dist/touchable-opacity.js +76 -0
  119. package/dist/touchable-opacity.js.map +1 -0
  120. package/dist/transforms.d.ts +2 -0
  121. package/dist/transforms.js +17 -0
  122. package/dist/transforms.js.map +1 -0
  123. package/dist/view-base.d.ts +332 -0
  124. package/dist/view-base.js +534 -0
  125. package/dist/view-base.js.map +1 -0
  126. package/dist/view.d.ts +12 -0
  127. package/dist/view.js +18 -0
  128. package/dist/view.js.map +1 -0
  129. package/dist/virtual-list.d.ts +530 -0
  130. package/dist/virtual-list.js +1150 -0
  131. package/dist/virtual-list.js.map +1 -0
  132. package/dist/worklet-scroll.d.ts +13 -0
  133. package/dist/worklet-scroll.js +49 -0
  134. package/dist/worklet-scroll.js.map +1 -0
  135. package/dist/worklet-style.d.ts +13 -0
  136. package/dist/worklet-style.js +47 -0
  137. package/dist/worklet-style.js.map +1 -0
  138. package/dist/worklets.d.ts +89 -0
  139. package/dist/worklets.js +42 -0
  140. package/dist/worklets.js.map +1 -0
  141. package/dist/written-props.d.ts +6 -0
  142. package/dist/written-props.js +180 -0
  143. package/dist/written-props.js.map +1 -0
  144. package/package.json +88 -3
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Platform capability: React Native's animation graph.
3
+ *
4
+ * React Native's `Animated` is worth reusing rather than reimplementing. Of the 45 files in
5
+ * `Libraries/Animated`, only 11 touch React, and all of them are the `components/*` wrappers,
6
+ * `createAnimatedComponent` and the hooks. The graph itself - values, interpolations, styles,
7
+ * timing, spring, decay, easing - and the native driver bridge are React-free.
8
+ *
9
+ * It is injected rather than imported for the same reason keyboard metrics are: the components
10
+ * package stays runnable under Node, where React Native's Flow-typed source cannot even be
11
+ * parsed, and a test can drive an animation without a device.
12
+ *
13
+ * Apps do not wire this at all: `AnimatedStyle` in `../animations.ts` carries it as its own
14
+ * provider, so importing the directive is the whole setup. The token is what makes that possible
15
+ * without the components package importing React Native, and what lets a test drive an animation
16
+ * with no device.
17
+ */
18
+ import { InjectionToken } from '@angular/core';
19
+ export const ANIMATION = new InjectionToken('angular-native.animation');
20
+ //# sourceMappingURL=animation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.js","sourceRoot":"","sources":["../src/animation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAyB/C,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,cAAc,CAAmB,0BAA0B,CAAC,CAAC","sourcesContent":["/**\n * Platform capability: React Native's animation graph.\n *\n * React Native's `Animated` is worth reusing rather than reimplementing. Of the 45 files in\n * `Libraries/Animated`, only 11 touch React, and all of them are the `components/*` wrappers,\n * `createAnimatedComponent` and the hooks. The graph itself - values, interpolations, styles,\n * timing, spring, decay, easing - and the native driver bridge are React-free.\n *\n * It is injected rather than imported for the same reason keyboard metrics are: the components\n * package stays runnable under Node, where React Native's Flow-typed source cannot even be\n * parsed, and a test can drive an animation without a device.\n *\n * Apps do not wire this at all: `AnimatedStyle` in `../animations.ts` carries it as its own\n * provider, so importing the directive is the whole setup. The token is what makes that possible\n * without the components package importing React Native, and what lets a test drive an animation\n * with no device.\n */\nimport { InjectionToken } from '@angular/core';\n\n/** One element's animated props, for as long as that element is alive. */\nexport interface AnimatedPropsHandle {\n /** Start observing the values. Until this runs, nothing reports a frame. */\n attach(): void;\n /** Stop observing, and release the native side if it was driving. */\n detach(): void;\n /** The current values, flattened the way a style object is. */\n read(): Record<string, unknown>;\n /**\n * Tell the graph which view the native driver should write to, by react tag. Safe to call\n * before any animation starts: React Native connects then, or later when one goes native.\n */\n connect(tag: number): void;\n}\n\nexport interface AnimationBackend {\n /**\n * Wrap a style that may contain animated values. `onFrame` fires on every frame the graph\n * advances in JavaScript, and never while the native driver owns the animation.\n */\n props(style: Record<string, unknown>, onFrame: () => void): AnimatedPropsHandle;\n}\n\nexport const ANIMATION = new InjectionToken<AnimationBackend>('angular-native.animation');\n"]}
@@ -0,0 +1,8 @@
1
+ import { AnimatedStyleBase } from './animated-style.ts';
2
+ import * as i0 from "@angular/core";
3
+ export { Animated } from './animated.ts';
4
+ export { Easing } from './easing.ts';
5
+ export declare class AnimatedStyle extends AnimatedStyleBase {
6
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnimatedStyle, never>;
7
+ static ɵdir: i0.ɵɵDirectiveDeclaration<AnimatedStyle, "[animatedStyle]", never, {}, {}, never, never, true, never>;
8
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `animations.ts`, for a browser build.
3
+ *
4
+ * A web bundler resolves `@ng-native/components/animations` here, through the `browser`
5
+ * condition in this package's `exports`; Metro, on a device, never sets that condition and gets
6
+ * the native file. The names are the same on both sides, so the component that imports
7
+ * `AnimatedStyle`, `Animated` and `Easing` from there is one component on both platforms.
8
+ *
9
+ * Nothing here reaches React Native. The graph is `animated.ts`, stepped by
10
+ * `requestAnimationFrame`, and every frame is written through `setProp(node, 'style', ...)` by the
11
+ * same directive the device uses.
12
+ */
13
+ import { Directive } from '@angular/core';
14
+ import { animationBackend } from "./animated.js";
15
+ import { AnimatedStyleBase } from "./animated-style.js";
16
+ import { ANIMATION } from "./animation.js";
17
+ import * as i0 from "@angular/core";
18
+ export { Animated } from "./animated.js";
19
+ export { Easing } from "./easing.js";
20
+ export class AnimatedStyle extends AnimatedStyleBase {
21
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: AnimatedStyle, deps: null, target: i0.ɵɵFactoryTarget.Directive });
22
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: AnimatedStyle, isStandalone: true, selector: "[animatedStyle]", providers: [{ provide: ANIMATION, useValue: animationBackend }], usesInheritance: true, ngImport: i0 });
23
+ }
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: AnimatedStyle, decorators: [{
25
+ type: Directive,
26
+ args: [{
27
+ selector: '[animatedStyle]',
28
+ providers: [{ provide: ANIMATION, useValue: animationBackend }],
29
+ }]
30
+ }] });
31
+ //# sourceMappingURL=animations-web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animations-web.js","sourceRoot":"","sources":["../src/animations-web.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;;AAE3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAMrC,MAAM,OAAO,aAAc,SAAQ,iBAAiB;uGAAvC,aAAa;2FAAb,aAAa,8DAFb,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;;2FAEpD,aAAa;kBAJzB,SAAS;mBAAC;oBACT,QAAQ,EAAE,iBAAiB;oBAC3B,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;iBAChE","sourcesContent":["/**\n * `animations.ts`, for a browser build.\n *\n * A web bundler resolves `@ng-native/components/animations` here, through the `browser`\n * condition in this package's `exports`; Metro, on a device, never sets that condition and gets\n * the native file. The names are the same on both sides, so the component that imports\n * `AnimatedStyle`, `Animated` and `Easing` from there is one component on both platforms.\n *\n * Nothing here reaches React Native. The graph is `animated.ts`, stepped by\n * `requestAnimationFrame`, and every frame is written through `setProp(node, 'style', ...)` by the\n * same directive the device uses.\n */\nimport { Directive } from '@angular/core';\nimport { animationBackend } from './animated.ts';\nimport { AnimatedStyleBase } from './animated-style.ts';\nimport { ANIMATION } from './animation.ts';\n\nexport { Animated } from './animated.ts';\nexport { Easing } from './easing.ts';\n\n@Directive({\n selector: '[animatedStyle]',\n providers: [{ provide: ANIMATION, useValue: animationBackend }],\n})\nexport class AnimatedStyle extends AnimatedStyleBase {}\n"]}
@@ -0,0 +1,7 @@
1
+ import { AnimatedStyleBase } from './animated-style.ts';
2
+ import * as i0 from "@angular/core";
3
+ export { Animated, Easing } from 'react-native';
4
+ export declare class AnimatedStyle extends AnimatedStyleBase {
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnimatedStyle, never>;
6
+ static ɵdir: i0.ɵɵDirectiveDeclaration<AnimatedStyle, "[animatedStyle]", never, {}, {}, never, never, true, never>;
7
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Everything an app needs to animate, in one provider.
3
+ *
4
+ * Deliberately outside the barrel: this file deep-imports React Native's
5
+ * animation graph, which is Flow source that Node cannot parse. Keeping it here means the rest of
6
+ * the package stays runnable under Node, which is what the whole test suite depends on. A browser
7
+ * build never sees this file: the package's `exports` send it to `animations-web.ts` instead.
8
+ *
9
+ * ```ts
10
+ * mount(rootTag, App, fabric, { providers: [provideAnimations()] });
11
+ * ```
12
+ *
13
+ * Note what this cannot do. Angular decides whether `animate.enter` and `animate.leave` do
14
+ * anything the moment `@angular/core` is evaluated, by reading a global; a provider runs long
15
+ * after that, so those two need a Metro polyfill instead and no provider can stand in for it. The
16
+ * `withAngularNative` preset adds it; this checks that it happened and says so if it did not.
17
+ */
18
+ // @ts-expect-error React Native ships its internals as Flow, so the deep import has no types.
19
+ // The shape used here is declared just below; it is four methods.
20
+ import Untyped from 'react-native/Libraries/Animated/nodes/AnimatedProps';
21
+ import { Directive } from '@angular/core';
22
+ import { AnimatedStyleBase } from "./animated-style.js";
23
+ import { ANIMATION } from "./animation.js";
24
+ import * as i0 from "@angular/core";
25
+ // The graph an app builds its values from, under the names a browser build exports too (see
26
+ // `animations-web.ts`), so one import serves a component on both platforms.
27
+ export { Animated, Easing } from 'react-native';
28
+ /**
29
+ * `AnimatedProps` is what `createAnimatedComponent` uses, and there is no public equivalent.
30
+ * Everything above it in that file is React, and none of it is wanted here.
31
+ */
32
+ const AnimatedProps = Untyped;
33
+ const backend = {
34
+ props: (style, onFrame) => {
35
+ const props = new AnimatedProps({ style }, onFrame);
36
+ return {
37
+ attach: () => props.__attach(),
38
+ detach: () => props.__detach(),
39
+ read: () => props.__getValue().style ?? {},
40
+ // A number is all `findNodeHandle` needs, so the graph can address one of our nodes with no
41
+ // React instance anywhere. React Native connects the view now if an animation has already
42
+ // gone native, and remembers the tag for the moment one does.
43
+ connect: (tag) => props.setNativeView(tag),
44
+ };
45
+ },
46
+ };
47
+ export class AnimatedStyle extends AnimatedStyleBase {
48
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: AnimatedStyle, deps: null, target: i0.ɵɵFactoryTarget.Directive });
49
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: AnimatedStyle, isStandalone: true, selector: "[animatedStyle]", providers: [{ provide: ANIMATION, useValue: backend }], usesInheritance: true, ngImport: i0 });
50
+ }
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: AnimatedStyle, decorators: [{
52
+ type: Directive,
53
+ args: [{
54
+ selector: '[animatedStyle]',
55
+ providers: [{ provide: ANIMATION, useValue: backend }],
56
+ }]
57
+ }] });
58
+ //# sourceMappingURL=animations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animations.js","sourceRoot":"","sources":["../src/animations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,8FAA8F;AAC9F,kEAAkE;AAClE,OAAO,OAAO,MAAM,qDAAqD,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAyB,MAAM,gBAAgB,CAAC;;AAElE,4FAA4F;AAC5F,4EAA4E;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAchD;;;GAGG;AACH,MAAM,aAAa,GAAG,OAGA,CAAC;AACvB,MAAM,OAAO,GAAqB;IAChC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO;YACL,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE;YAC9B,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE;YAC9B,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,KAAK,IAAI,EAAE;YAC1C,4FAA4F;YAC5F,0FAA0F;YAC1F,8DAA8D;YAC9D,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC;SAC3C,CAAC;IACJ,CAAC;CACF,CAAC;AAMF,MAAM,OAAO,aAAc,SAAQ,iBAAiB;uGAAvC,aAAa;2FAAb,aAAa,8DAFb,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;;2FAE3C,aAAa;kBAJzB,SAAS;mBAAC;oBACT,QAAQ,EAAE,iBAAiB;oBAC3B,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;iBACvD","sourcesContent":["/**\n * Everything an app needs to animate, in one provider.\n *\n * Deliberately outside the barrel: this file deep-imports React Native's\n * animation graph, which is Flow source that Node cannot parse. Keeping it here means the rest of\n * the package stays runnable under Node, which is what the whole test suite depends on. A browser\n * build never sees this file: the package's `exports` send it to `animations-web.ts` instead.\n *\n * ```ts\n * mount(rootTag, App, fabric, { providers: [provideAnimations()] });\n * ```\n *\n * Note what this cannot do. Angular decides whether `animate.enter` and `animate.leave` do\n * anything the moment `@angular/core` is evaluated, by reading a global; a provider runs long\n * after that, so those two need a Metro polyfill instead and no provider can stand in for it. The\n * `withAngularNative` preset adds it; this checks that it happened and says so if it did not.\n */\n// @ts-expect-error React Native ships its internals as Flow, so the deep import has no types.\n// The shape used here is declared just below; it is four methods.\nimport Untyped from 'react-native/Libraries/Animated/nodes/AnimatedProps';\nimport { Directive } from '@angular/core';\nimport { AnimatedStyleBase } from './animated-style.ts';\nimport { ANIMATION, type AnimationBackend } from './animation.ts';\n\n// The graph an app builds its values from, under the names a browser build exports too (see\n// `animations-web.ts`), so one import serves a component on both platforms.\nexport { Animated, Easing } from 'react-native';\n\n/**\n * What `AnimatedProps` gives us. `setNativeView` takes anything `findNodeHandle` accepts, and\n * that includes a plain number, which is how an animated graph reaches one of our nodes with no\n * React instance in sight.\n */\ninterface AnimatedPropsNode {\n __attach(): void;\n __detach(): void;\n __getValue(): { style?: Record<string, unknown> };\n setNativeView(viewTag: number): void;\n}\n\n/**\n * `AnimatedProps` is what `createAnimatedComponent` uses, and there is no public equivalent.\n * Everything above it in that file is React, and none of it is wanted here.\n */\nconst AnimatedProps = Untyped as new (\n props: { [key: string]: unknown },\n callback: () => void,\n) => AnimatedPropsNode;\nconst backend: AnimationBackend = {\n props: (style, onFrame) => {\n const props = new AnimatedProps({ style }, onFrame);\n return {\n attach: () => props.__attach(),\n detach: () => props.__detach(),\n read: () => props.__getValue().style ?? {},\n // A number is all `findNodeHandle` needs, so the graph can address one of our nodes with no\n // React instance anywhere. React Native connects the view now if an animation has already\n // gone native, and remembers the tag for the moment one does.\n connect: (tag) => props.setNativeView(tag),\n };\n },\n};\n\n@Directive({\n selector: '[animatedStyle]',\n providers: [{ provide: ANIMATION, useValue: backend }],\n})\nexport class AnimatedStyle extends AnimatedStyleBase {}\n"]}
@@ -0,0 +1,33 @@
1
+ import { type ModelSignal, type SimpleChanges } from '@angular/core';
2
+ /**
3
+ * A `model()` that native edits, with React Native's controlled-component rule: once something
4
+ * outside binds the model, its value is the truth, and a native edit is only a proposal.
5
+ *
6
+ * The model has to stay a model, because that is the whole of the Signal Forms contract. What
7
+ * goes wrong with a plain `set` is a refusal. The user flips a switch, `set(true)` emits, the app
8
+ * keeps `false` and writes it back - but that is the value its binding last wrote, so Angular
9
+ * sends nothing down, and the model is left saying `true` while the app says `false`. Nothing
10
+ * downstream can see the disagreement, because the model and native agree with each other.
11
+ *
12
+ * So `propose` emits the new value and then puts the model back where the parent last put it,
13
+ * without emitting again. If the parent takes the value, its binding changes and writes it in
14
+ * during change detection, as it would for any other input; if it refuses, the binding stays
15
+ * quiet and the model is already back at the value the app kept. Either way, by the time the
16
+ * pass has rendered the model says what the app says, and the component compares that with what
17
+ * native is showing.
18
+ *
19
+ * The write back goes through the model's input node, the same call Angular makes for a binding,
20
+ * which is the one way to set a model without emitting. Nothing bound means nothing to defer to,
21
+ * and the model keeps what native reported, as an uncontrolled RN component does.
22
+ */
23
+ export declare class ControlledModel<T> {
24
+ /** Whether a binding or `FormField` has ever written the model. */
25
+ private bound;
26
+ private readonly model;
27
+ private readonly name;
28
+ constructor(model: ModelSignal<T>, name: string);
29
+ /** Call from `ngOnChanges`. A template binding and `FormField` both arrive through it. */
30
+ noteChanges(changes: SimpleChanges): void;
31
+ /** A native edit: emit it, and leave the model to the parent if it has one. */
32
+ propose(value: T): void;
33
+ }
@@ -0,0 +1,47 @@
1
+ import { untracked, ɵSIGNAL as SIGNAL } from '@angular/core';
2
+ /**
3
+ * A `model()` that native edits, with React Native's controlled-component rule: once something
4
+ * outside binds the model, its value is the truth, and a native edit is only a proposal.
5
+ *
6
+ * The model has to stay a model, because that is the whole of the Signal Forms contract. What
7
+ * goes wrong with a plain `set` is a refusal. The user flips a switch, `set(true)` emits, the app
8
+ * keeps `false` and writes it back - but that is the value its binding last wrote, so Angular
9
+ * sends nothing down, and the model is left saying `true` while the app says `false`. Nothing
10
+ * downstream can see the disagreement, because the model and native agree with each other.
11
+ *
12
+ * So `propose` emits the new value and then puts the model back where the parent last put it,
13
+ * without emitting again. If the parent takes the value, its binding changes and writes it in
14
+ * during change detection, as it would for any other input; if it refuses, the binding stays
15
+ * quiet and the model is already back at the value the app kept. Either way, by the time the
16
+ * pass has rendered the model says what the app says, and the component compares that with what
17
+ * native is showing.
18
+ *
19
+ * The write back goes through the model's input node, the same call Angular makes for a binding,
20
+ * which is the one way to set a model without emitting. Nothing bound means nothing to defer to,
21
+ * and the model keeps what native reported, as an uncontrolled RN component does.
22
+ */
23
+ export class ControlledModel {
24
+ /** Whether a binding or `FormField` has ever written the model. */
25
+ bound = false;
26
+ model;
27
+ name;
28
+ constructor(model, name) {
29
+ this.model = model;
30
+ this.name = name;
31
+ }
32
+ /** Call from `ngOnChanges`. A template binding and `FormField` both arrive through it. */
33
+ noteChanges(changes) {
34
+ if (this.name in changes)
35
+ this.bound = true;
36
+ }
37
+ /** A native edit: emit it, and leave the model to the parent if it has one. */
38
+ propose(value) {
39
+ const held = untracked(this.model);
40
+ this.model.set(value);
41
+ if (!this.bound)
42
+ return;
43
+ const node = this.model[SIGNAL];
44
+ node.applyValueToInputSignal(node, held);
45
+ }
46
+ }
47
+ //# sourceMappingURL=controlled-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controlled-model.js","sourceRoot":"","sources":["../src/controlled-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,SAAS,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAEnG;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,eAAe;IAC1B,mEAAmE;IAC3D,KAAK,GAAG,KAAK,CAAC;IACL,KAAK,CAAiB;IACtB,IAAI,CAAS;IAE9B,YAAY,KAAqB,EAAE,IAAY;QAC7C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,0FAA0F;IAC1F,WAAW,CAAC,OAAsB;QAChC,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO;YAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IAC9C,CAAC;IAED,+EAA+E;IAC/E,OAAO,CAAC,KAAQ;QACd,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;CACF","sourcesContent":["import { type ModelSignal, type SimpleChanges, untracked, ɵSIGNAL as SIGNAL } from '@angular/core';\n\n/**\n * A `model()` that native edits, with React Native's controlled-component rule: once something\n * outside binds the model, its value is the truth, and a native edit is only a proposal.\n *\n * The model has to stay a model, because that is the whole of the Signal Forms contract. What\n * goes wrong with a plain `set` is a refusal. The user flips a switch, `set(true)` emits, the app\n * keeps `false` and writes it back - but that is the value its binding last wrote, so Angular\n * sends nothing down, and the model is left saying `true` while the app says `false`. Nothing\n * downstream can see the disagreement, because the model and native agree with each other.\n *\n * So `propose` emits the new value and then puts the model back where the parent last put it,\n * without emitting again. If the parent takes the value, its binding changes and writes it in\n * during change detection, as it would for any other input; if it refuses, the binding stays\n * quiet and the model is already back at the value the app kept. Either way, by the time the\n * pass has rendered the model says what the app says, and the component compares that with what\n * native is showing.\n *\n * The write back goes through the model's input node, the same call Angular makes for a binding,\n * which is the one way to set a model without emitting. Nothing bound means nothing to defer to,\n * and the model keeps what native reported, as an uncontrolled RN component does.\n */\nexport class ControlledModel<T> {\n /** Whether a binding or `FormField` has ever written the model. */\n private bound = false;\n private readonly model: ModelSignal<T>;\n private readonly name: string;\n\n constructor(model: ModelSignal<T>, name: string) {\n this.model = model;\n this.name = name;\n }\n\n /** Call from `ngOnChanges`. A template binding and `FormField` both arrive through it. */\n noteChanges(changes: SimpleChanges): void {\n if (this.name in changes) this.bound = true;\n }\n\n /** A native edit: emit it, and leave the model to the parent if it has one. */\n propose(value: T): void {\n const held = untracked(this.model);\n this.model.set(value);\n if (!this.bound) return;\n const node = this.model[SIGNAL];\n node.applyValueToInputSignal(node, held);\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ export type EasingFunction = (t: number) => number;
2
+ export declare const Easing: {
3
+ step0: (n: number) => number;
4
+ step1: (n: number) => number;
5
+ linear: (t: number) => number;
6
+ /** CSS's `ease-in`, which is what React Native calls `ease`. */
7
+ ease: (t: number) => number;
8
+ quad: (t: number) => number;
9
+ cubic: (t: number) => number;
10
+ poly: (n: number) => EasingFunction;
11
+ sin: (t: number) => number;
12
+ circle: (t: number) => number;
13
+ exp: (t: number) => number;
14
+ elastic: (bounciness?: number) => EasingFunction;
15
+ back: (s?: number) => EasingFunction;
16
+ bounce: (t: number) => number;
17
+ bezier: (x1: number, y1: number, x2: number, y2: number) => EasingFunction;
18
+ in: (easing: EasingFunction) => EasingFunction;
19
+ out: (easing: EasingFunction) => EasingFunction;
20
+ inOut: (easing: EasingFunction) => EasingFunction;
21
+ };
package/dist/easing.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * React Native's `Easing`, for the browser build of `animations.ts`.
3
+ *
4
+ * The same functions under the same names, each the same formula as React Native's
5
+ * `Libraries/Animated/Easing.js`, so a curve an app names eases identically on both platforms. The
6
+ * one piece of real arithmetic, solving a cubic bezier, is the engine's own: CSS transitions
7
+ * already need it, and two solvers would be two chances to disagree.
8
+ */
9
+ import { bezier } from '@ng-native/fabric';
10
+ let ease;
11
+ export const Easing = {
12
+ step0: (n) => (n > 0 ? 1 : 0),
13
+ step1: (n) => (n >= 1 ? 1 : 0),
14
+ linear: (t) => t,
15
+ /** CSS's `ease-in`, which is what React Native calls `ease`. */
16
+ ease: (t) => (ease ??= Easing.bezier(0.42, 0, 1, 1))(t),
17
+ quad: (t) => t * t,
18
+ cubic: (t) => t * t * t,
19
+ poly: (n) => (t) => Math.pow(t, n),
20
+ sin: (t) => 1 - Math.cos((t * Math.PI) / 2),
21
+ circle: (t) => 1 - Math.sqrt(1 - t * t),
22
+ exp: (t) => Math.pow(2, 10 * (t - 1)),
23
+ elastic: (bounciness = 1) => {
24
+ const p = bounciness * Math.PI;
25
+ return (t) => 1 - Math.pow(Math.cos((t * Math.PI) / 2), 3) * Math.cos(t * p);
26
+ },
27
+ back: (s = 1.70158) => (t) => t * t * ((s + 1) * t - s),
28
+ bounce: (t) => {
29
+ if (t < 1 / 2.75)
30
+ return 7.5625 * t * t;
31
+ if (t < 2 / 2.75) {
32
+ const t2 = t - 1.5 / 2.75;
33
+ return 7.5625 * t2 * t2 + 0.75;
34
+ }
35
+ if (t < 2.5 / 2.75) {
36
+ const t2 = t - 2.25 / 2.75;
37
+ return 7.5625 * t2 * t2 + 0.9375;
38
+ }
39
+ const t2 = t - 2.625 / 2.75;
40
+ return 7.5625 * t2 * t2 + 0.984375;
41
+ },
42
+ bezier: (x1, y1, x2, y2) => {
43
+ const points = [x1, y1, x2, y2];
44
+ return (t) => bezier(points, t);
45
+ },
46
+ in: (easing) => easing,
47
+ out: (easing) => (t) => 1 - easing(1 - t),
48
+ inOut: (easing) => (t) => t < 0.5 ? easing(t * 2) / 2 : 1 - easing((1 - t) * 2) / 2,
49
+ };
50
+ //# sourceMappingURL=easing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"easing.js","sourceRoot":"","sources":["../src/easing.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * React Native's `Easing`, for the browser build of `animations.ts`.\n *\n * The same functions under the same names, each the same formula as React Native's\n * `Libraries/Animated/Easing.js`, so a curve an app names eases identically on both platforms. The\n * one piece of real arithmetic, solving a cubic bezier, is the engine's own: CSS transitions\n * already need it, and two solvers would be two chances to disagree.\n */\nimport { bezier } from '@ng-native/fabric';\n\nexport type EasingFunction = (t: number) => number;\n\nlet ease: EasingFunction | undefined;\n\nexport const Easing = {\n step0: (n: number): number => (n > 0 ? 1 : 0),\n step1: (n: number): number => (n >= 1 ? 1 : 0),\n linear: (t: number): number => t,\n /** CSS's `ease-in`, which is what React Native calls `ease`. */\n ease: (t: number): number => (ease ??= Easing.bezier(0.42, 0, 1, 1))(t),\n quad: (t: number): number => t * t,\n cubic: (t: number): number => t * t * t,\n poly:\n (n: number): EasingFunction =>\n (t) =>\n Math.pow(t, n),\n sin: (t: number): number => 1 - Math.cos((t * Math.PI) / 2),\n circle: (t: number): number => 1 - Math.sqrt(1 - t * t),\n exp: (t: number): number => Math.pow(2, 10 * (t - 1)),\n elastic: (bounciness = 1): EasingFunction => {\n const p = bounciness * Math.PI;\n return (t) => 1 - Math.pow(Math.cos((t * Math.PI) / 2), 3) * Math.cos(t * p);\n },\n back:\n (s = 1.70158): EasingFunction =>\n (t) =>\n t * t * ((s + 1) * t - s),\n bounce: (t: number): number => {\n if (t < 1 / 2.75) return 7.5625 * t * t;\n if (t < 2 / 2.75) {\n const t2 = t - 1.5 / 2.75;\n return 7.5625 * t2 * t2 + 0.75;\n }\n if (t < 2.5 / 2.75) {\n const t2 = t - 2.25 / 2.75;\n return 7.5625 * t2 * t2 + 0.9375;\n }\n const t2 = t - 2.625 / 2.75;\n return 7.5625 * t2 * t2 + 0.984375;\n },\n bezier: (x1: number, y1: number, x2: number, y2: number): EasingFunction => {\n const points = [x1, y1, x2, y2];\n return (t) => bezier(points, t);\n },\n in: (easing: EasingFunction): EasingFunction => easing,\n out:\n (easing: EasingFunction): EasingFunction =>\n (t) =>\n 1 - easing(1 - t),\n inOut:\n (easing: EasingFunction): EasingFunction =>\n (t) =>\n t < 0.5 ? easing(t * 2) / 2 : 1 - easing((1 - t) * 2) / 2,\n};\n"]}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * The `nativeEvent` payloads native sends, so a handler can be typed rather than cast.
3
+ *
4
+ * Events on a primitive are element events, bound with Angular's `(name)` syntax and routed by
5
+ * the renderer to Fabric's `topName`, so `(layout)="onLayout($event)"` receives a
6
+ * `NativeSyntheticEvent<LayoutPayload>`. Nothing here is emitted from a component: a listener the
7
+ * component registered itself would opt every instance into events such as `topLayout`, which
8
+ * native only sends when something asks.
9
+ */
10
+ import type { NativeSyntheticEvent, TouchPayload } from '@ng-native/fabric';
11
+ export interface Rect {
12
+ readonly x: number;
13
+ readonly y: number;
14
+ readonly width: number;
15
+ readonly height: number;
16
+ }
17
+ export interface Size {
18
+ readonly width: number;
19
+ readonly height: number;
20
+ }
21
+ export interface Point {
22
+ readonly x: number;
23
+ readonly y: number;
24
+ }
25
+ export interface Insets {
26
+ readonly top?: number;
27
+ readonly left?: number;
28
+ readonly bottom?: number;
29
+ readonly right?: number;
30
+ }
31
+ /** `(layout)`: the view's frame, in its parent's coordinates. Needs `onLayout` to be opted in. */
32
+ export interface LayoutPayload {
33
+ readonly layout: Rect;
34
+ }
35
+ export type LayoutEvent = NativeSyntheticEvent<LayoutPayload>;
36
+ /** `(touchStart)`, `(touchMove)`, `(touchEnd)`, `(touchCancel)`. */
37
+ export interface TouchEventPayload extends TouchPayload {
38
+ readonly touches?: readonly TouchPayload[];
39
+ readonly changedTouches?: readonly TouchPayload[];
40
+ }
41
+ export type TouchEvent = NativeSyntheticEvent<TouchEventPayload>;
42
+ /** `(scroll)` and the drag and momentum events on a scroll view. */
43
+ export interface ScrollPayload {
44
+ readonly contentOffset: Point;
45
+ readonly contentSize: Size;
46
+ readonly layoutMeasurement: Size;
47
+ readonly contentInset: Required<Insets>;
48
+ readonly zoomScale: number;
49
+ /** Present on the drag-end and momentum events. */
50
+ readonly velocity?: Point;
51
+ readonly responderIgnoreScroll?: boolean;
52
+ readonly targetContentOffset?: Point;
53
+ }
54
+ export type ScrollEvent = NativeSyntheticEvent<ScrollPayload>;
55
+ /** `(contentSizeChange)` on a scroll view: the new size of the content view. */
56
+ export type ContentSizeChangeEvent = NativeSyntheticEvent<Size>;
57
+ /** One laid-out line, from `(textLayout)`. */
58
+ export interface TextLayoutLine extends Rect {
59
+ readonly ascender: number;
60
+ readonly capHeight: number;
61
+ readonly descender: number;
62
+ readonly text: string;
63
+ readonly xHeight: number;
64
+ }
65
+ export interface TextLayoutPayload {
66
+ readonly lines: readonly TextLayoutLine[];
67
+ }
68
+ export type TextLayoutEvent = NativeSyntheticEvent<TextLayoutPayload>;
69
+ /** `(change)` on a text input, and the value the model is set from. */
70
+ export interface TextInputChangePayload {
71
+ readonly text: string;
72
+ readonly eventCount: number;
73
+ readonly target: number;
74
+ }
75
+ export type TextInputChangeEvent = NativeSyntheticEvent<TextInputChangePayload>;
76
+ /** `(submitEditing)` and `(endEditing)`. */
77
+ export type TextInputEditingEvent = NativeSyntheticEvent<TextInputChangePayload>;
78
+ /** `(focus)` and `(blur)` on a text input. */
79
+ export interface TextInputFocusPayload {
80
+ readonly target: number;
81
+ readonly eventCount?: number;
82
+ readonly text?: string;
83
+ }
84
+ export type TextInputFocusEvent = NativeSyntheticEvent<TextInputFocusPayload>;
85
+ /** `(selectionChange)`. */
86
+ export interface SelectionChangePayload {
87
+ readonly selection: {
88
+ readonly start: number;
89
+ readonly end: number;
90
+ };
91
+ readonly target: number;
92
+ }
93
+ export type SelectionChangeEvent = NativeSyntheticEvent<SelectionChangePayload>;
94
+ /** `(keyPress)`: `key` is the character, or `Backspace`, `Enter`, `Tab` and so on. */
95
+ export interface KeyPressPayload {
96
+ readonly key: string;
97
+ readonly target?: number;
98
+ readonly eventCount?: number;
99
+ }
100
+ export type KeyPressEvent = NativeSyntheticEvent<KeyPressPayload>;
101
+ /** `(contentSizeChange)` on a multiline text input. */
102
+ export interface TextInputContentSizePayload {
103
+ readonly contentSize: Size;
104
+ readonly target: number;
105
+ }
106
+ export type TextInputContentSizeEvent = NativeSyntheticEvent<TextInputContentSizePayload>;
107
+ /** `(scroll)` on a multiline text input. */
108
+ export interface TextInputScrollPayload {
109
+ readonly contentOffset: Point;
110
+ }
111
+ export type TextInputScrollEvent = NativeSyntheticEvent<TextInputScrollPayload>;
112
+ /** `(change)` on a switch. */
113
+ export interface SwitchChangePayload {
114
+ readonly value: boolean;
115
+ readonly target: number;
116
+ }
117
+ export type SwitchChangeEvent = NativeSyntheticEvent<SwitchChangePayload>;
118
+ /** `(load)` on an image: what was decoded. */
119
+ export interface ImageLoadPayload {
120
+ readonly source: {
121
+ readonly uri: string;
122
+ readonly width: number;
123
+ readonly height: number;
124
+ };
125
+ }
126
+ export type ImageLoadEvent = NativeSyntheticEvent<ImageLoadPayload>;
127
+ /** `(error)` on an image. */
128
+ export interface ImageErrorPayload {
129
+ readonly error: string;
130
+ }
131
+ export type ImageErrorEvent = NativeSyntheticEvent<ImageErrorPayload>;
132
+ /** `(progress)` on an image, iOS only. */
133
+ export interface ImageProgressPayload {
134
+ readonly loaded: number;
135
+ readonly total: number;
136
+ }
137
+ export type ImageProgressEvent = NativeSyntheticEvent<ImageProgressPayload>;
138
+ /** `(orientationChange)` on a modal, iOS only. */
139
+ export interface OrientationChangePayload {
140
+ readonly orientation: 'portrait' | 'landscape';
141
+ }
142
+ export type OrientationChangeEvent = NativeSyntheticEvent<OrientationChangePayload>;
143
+ /** `(accessibilityAction)`: which of the view's declared actions the assistive technology fired. */
144
+ export interface AccessibilityActionPayload {
145
+ readonly actionName: string;
146
+ }
147
+ export type AccessibilityActionEvent = NativeSyntheticEvent<AccessibilityActionPayload>;
148
+ declare global {
149
+ interface HTMLElementEventMap {
150
+ layout: LayoutEvent;
151
+ touchStart: TouchEvent;
152
+ touchMove: TouchEvent;
153
+ touchEnd: TouchEvent;
154
+ touchCancel: TouchEvent;
155
+ scrollBeginDrag: ScrollEvent;
156
+ scrollEndDrag: ScrollEvent;
157
+ momentumScrollBegin: ScrollEvent;
158
+ momentumScrollEnd: ScrollEvent;
159
+ /** A scroll view's content, or a multiline text input's. */
160
+ contentSizeChange: ContentSizeChangeEvent | TextInputContentSizeEvent;
161
+ textLayout: TextLayoutEvent;
162
+ submitEditing: TextInputEditingEvent;
163
+ endEditing: TextInputEditingEvent;
164
+ selectionChange: SelectionChangeEvent;
165
+ keyPress: KeyPressEvent;
166
+ orientationChange: OrientationChangeEvent;
167
+ accessibilityAction: AccessibilityActionEvent;
168
+ }
169
+ }
package/dist/events.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * The `nativeEvent` payloads native sends, so a handler can be typed rather than cast.\n *\n * Events on a primitive are element events, bound with Angular's `(name)` syntax and routed by\n * the renderer to Fabric's `topName`, so `(layout)=\"onLayout($event)\"` receives a\n * `NativeSyntheticEvent<LayoutPayload>`. Nothing here is emitted from a component: a listener the\n * component registered itself would opt every instance into events such as `topLayout`, which\n * native only sends when something asks.\n */\nimport type { NativeSyntheticEvent, TouchPayload } from '@ng-native/fabric';\n\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\nexport interface Size {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface Insets {\n readonly top?: number;\n readonly left?: number;\n readonly bottom?: number;\n readonly right?: number;\n}\n\n/** `(layout)`: the view's frame, in its parent's coordinates. Needs `onLayout` to be opted in. */\nexport interface LayoutPayload {\n readonly layout: Rect;\n}\nexport type LayoutEvent = NativeSyntheticEvent<LayoutPayload>;\n\n/** `(touchStart)`, `(touchMove)`, `(touchEnd)`, `(touchCancel)`. */\nexport interface TouchEventPayload extends TouchPayload {\n readonly touches?: readonly TouchPayload[];\n readonly changedTouches?: readonly TouchPayload[];\n}\nexport type TouchEvent = NativeSyntheticEvent<TouchEventPayload>;\n\n/** `(scroll)` and the drag and momentum events on a scroll view. */\nexport interface ScrollPayload {\n readonly contentOffset: Point;\n readonly contentSize: Size;\n readonly layoutMeasurement: Size;\n readonly contentInset: Required<Insets>;\n readonly zoomScale: number;\n /** Present on the drag-end and momentum events. */\n readonly velocity?: Point;\n readonly responderIgnoreScroll?: boolean;\n readonly targetContentOffset?: Point;\n}\nexport type ScrollEvent = NativeSyntheticEvent<ScrollPayload>;\n\n/** `(contentSizeChange)` on a scroll view: the new size of the content view. */\nexport type ContentSizeChangeEvent = NativeSyntheticEvent<Size>;\n\n/** One laid-out line, from `(textLayout)`. */\nexport interface TextLayoutLine extends Rect {\n readonly ascender: number;\n readonly capHeight: number;\n readonly descender: number;\n readonly text: string;\n readonly xHeight: number;\n}\nexport interface TextLayoutPayload {\n readonly lines: readonly TextLayoutLine[];\n}\nexport type TextLayoutEvent = NativeSyntheticEvent<TextLayoutPayload>;\n\n/** `(change)` on a text input, and the value the model is set from. */\nexport interface TextInputChangePayload {\n readonly text: string;\n readonly eventCount: number;\n readonly target: number;\n}\nexport type TextInputChangeEvent = NativeSyntheticEvent<TextInputChangePayload>;\n\n/** `(submitEditing)` and `(endEditing)`. */\nexport type TextInputEditingEvent = NativeSyntheticEvent<TextInputChangePayload>;\n\n/** `(focus)` and `(blur)` on a text input. */\nexport interface TextInputFocusPayload {\n readonly target: number;\n readonly eventCount?: number;\n readonly text?: string;\n}\nexport type TextInputFocusEvent = NativeSyntheticEvent<TextInputFocusPayload>;\n\n/** `(selectionChange)`. */\nexport interface SelectionChangePayload {\n readonly selection: { readonly start: number; readonly end: number };\n readonly target: number;\n}\nexport type SelectionChangeEvent = NativeSyntheticEvent<SelectionChangePayload>;\n\n/** `(keyPress)`: `key` is the character, or `Backspace`, `Enter`, `Tab` and so on. */\nexport interface KeyPressPayload {\n readonly key: string;\n readonly target?: number;\n readonly eventCount?: number;\n}\nexport type KeyPressEvent = NativeSyntheticEvent<KeyPressPayload>;\n\n/** `(contentSizeChange)` on a multiline text input. */\nexport interface TextInputContentSizePayload {\n readonly contentSize: Size;\n readonly target: number;\n}\nexport type TextInputContentSizeEvent = NativeSyntheticEvent<TextInputContentSizePayload>;\n\n/** `(scroll)` on a multiline text input. */\nexport interface TextInputScrollPayload {\n readonly contentOffset: Point;\n}\nexport type TextInputScrollEvent = NativeSyntheticEvent<TextInputScrollPayload>;\n\n/** `(change)` on a switch. */\nexport interface SwitchChangePayload {\n readonly value: boolean;\n readonly target: number;\n}\nexport type SwitchChangeEvent = NativeSyntheticEvent<SwitchChangePayload>;\n\n/** `(load)` on an image: what was decoded. */\nexport interface ImageLoadPayload {\n readonly source: { readonly uri: string; readonly width: number; readonly height: number };\n}\nexport type ImageLoadEvent = NativeSyntheticEvent<ImageLoadPayload>;\n\n/** `(error)` on an image. */\nexport interface ImageErrorPayload {\n readonly error: string;\n}\nexport type ImageErrorEvent = NativeSyntheticEvent<ImageErrorPayload>;\n\n/** `(progress)` on an image, iOS only. */\nexport interface ImageProgressPayload {\n readonly loaded: number;\n readonly total: number;\n}\nexport type ImageProgressEvent = NativeSyntheticEvent<ImageProgressPayload>;\n\n/** `(orientationChange)` on a modal, iOS only. */\nexport interface OrientationChangePayload {\n readonly orientation: 'portrait' | 'landscape';\n}\nexport type OrientationChangeEvent = NativeSyntheticEvent<OrientationChangePayload>;\n\n/** `(accessibilityAction)`: which of the view's declared actions the assistive technology fired. */\nexport interface AccessibilityActionPayload {\n readonly actionName: string;\n}\nexport type AccessibilityActionEvent = NativeSyntheticEvent<AccessibilityActionPayload>;\n\n/*\n * The events above, by name, where Angular's template type-checker looks for an element event's\n * type. It types `$event` in `(layout)=\"...\"` from `HTMLElementEventMap`, so without these every\n * native event reads as a DOM `Event` and `$event.nativeEvent` fails to type-check. There is no\n * DOM here to be wrong about. Names the DOM already has - `scroll`, `change`, `focus`, `blur`,\n * `load`, `error`, `progress` - keep its `Event`: an interface cannot give them a second type.\n */\ndeclare global {\n interface HTMLElementEventMap {\n layout: LayoutEvent;\n touchStart: TouchEvent;\n touchMove: TouchEvent;\n touchEnd: TouchEvent;\n touchCancel: TouchEvent;\n scrollBeginDrag: ScrollEvent;\n scrollEndDrag: ScrollEvent;\n momentumScrollBegin: ScrollEvent;\n momentumScrollEnd: ScrollEvent;\n /** A scroll view's content, or a multiline text input's. */\n contentSizeChange: ContentSizeChangeEvent | TextInputContentSizeEvent;\n textLayout: TextLayoutEvent;\n submitEditing: TextInputEditingEvent;\n endEditing: TextInputEditingEvent;\n selectionChange: SelectionChangeEvent;\n keyPress: KeyPressEvent;\n orientationChange: OrientationChangeEvent;\n accessibilityAction: AccessibilityActionEvent;\n }\n}\n"]}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Platform capability: native gesture recognition, from react-native-gesture-handler.
3
+ *
4
+ * A gesture is recognised by the platform - a `UIPanGestureRecognizer`, an Android
5
+ * `GestureDetector` - rather than by our own responder negotiation. That is what makes a drag
6
+ * inside a scroll view behave, and what a pinch or a rotation needs to exist at all.
7
+ *
8
+ * Injected rather than imported for the reason everything in this shape is: the library reaches
9
+ * React Native's Flow source, which Node cannot parse. `NativeGesture` in `../gestures.ts` carries
10
+ * the real backend as its own provider, so importing the directive is the whole setup.
11
+ */
12
+ import { InjectionToken } from '@angular/core';
13
+ /**
14
+ * A gesture built by the library's own `Gesture` API: `Gesture.Pan()`, or a composition of
15
+ * several. Opaque here on purpose - the shape is the library's, and this package does not know it.
16
+ */
17
+ export type GestureSpec = object;
18
+ /** What a gesture is attached to: a node's react tag. */
19
+ export interface GestureTarget {
20
+ readonly tag: number;
21
+ }
22
+ export interface GestureBackend {
23
+ /** Attach `gesture` to `target`, and return the function that detaches it. */
24
+ attach(target: GestureTarget, gesture: GestureSpec): () => void;
25
+ }
26
+ export declare const GESTURES: InjectionToken<GestureBackend>;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Platform capability: native gesture recognition, from react-native-gesture-handler.
3
+ *
4
+ * A gesture is recognised by the platform - a `UIPanGestureRecognizer`, an Android
5
+ * `GestureDetector` - rather than by our own responder negotiation. That is what makes a drag
6
+ * inside a scroll view behave, and what a pinch or a rotation needs to exist at all.
7
+ *
8
+ * Injected rather than imported for the reason everything in this shape is: the library reaches
9
+ * React Native's Flow source, which Node cannot parse. `NativeGesture` in `../gestures.ts` carries
10
+ * the real backend as its own provider, so importing the directive is the whole setup.
11
+ */
12
+ import { InjectionToken } from '@angular/core';
13
+ export const GESTURES = new InjectionToken('angular-native.gestures');
14
+ //# sourceMappingURL=gesture-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gesture-backend.js","sourceRoot":"","sources":["../src/gesture-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAkB/C,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAiB,yBAAyB,CAAC,CAAC","sourcesContent":["/**\n * Platform capability: native gesture recognition, from react-native-gesture-handler.\n *\n * A gesture is recognised by the platform - a `UIPanGestureRecognizer`, an Android\n * `GestureDetector` - rather than by our own responder negotiation. That is what makes a drag\n * inside a scroll view behave, and what a pinch or a rotation needs to exist at all.\n *\n * Injected rather than imported for the reason everything in this shape is: the library reaches\n * React Native's Flow source, which Node cannot parse. `NativeGesture` in `../gestures.ts` carries\n * the real backend as its own provider, so importing the directive is the whole setup.\n */\nimport { InjectionToken } from '@angular/core';\n\n/**\n * A gesture built by the library's own `Gesture` API: `Gesture.Pan()`, or a composition of\n * several. Opaque here on purpose - the shape is the library's, and this package does not know it.\n */\nexport type GestureSpec = object;\n\n/** What a gesture is attached to: a node's react tag. */\nexport interface GestureTarget {\n readonly tag: number;\n}\n\nexport interface GestureBackend {\n /** Attach `gesture` to `target`, and return the function that detaches it. */\n attach(target: GestureTarget, gesture: GestureSpec): () => void;\n}\n\nexport const GESTURES = new InjectionToken<GestureBackend>('angular-native.gestures');\n"]}