@ng-native/components 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +78 -1
- package/dist/activity-indicator.d.ts +41 -0
- package/dist/activity-indicator.js +66 -0
- package/dist/activity-indicator.js.map +1 -0
- package/dist/animated-style.d.ts +31 -0
- package/dist/animated-style.js +102 -0
- package/dist/animated-style.js.map +1 -0
- package/dist/animated.d.ts +125 -0
- package/dist/animated.js +538 -0
- package/dist/animated.js.map +1 -0
- package/dist/animation.d.ts +40 -0
- package/dist/animation.js +20 -0
- package/dist/animation.js.map +1 -0
- package/dist/animations-web.d.ts +8 -0
- package/dist/animations-web.js +31 -0
- package/dist/animations-web.js.map +1 -0
- package/dist/animations.d.ts +7 -0
- package/dist/animations.js +58 -0
- package/dist/animations.js.map +1 -0
- package/dist/controlled-model.d.ts +33 -0
- package/dist/controlled-model.js +47 -0
- package/dist/controlled-model.js.map +1 -0
- package/dist/easing.d.ts +21 -0
- package/dist/easing.js +50 -0
- package/dist/easing.js.map +1 -0
- package/dist/events.d.ts +169 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/gesture-backend.d.ts +26 -0
- package/dist/gesture-backend.js +14 -0
- package/dist/gesture-backend.js.map +1 -0
- package/dist/gesture-dispatch.d.ts +67 -0
- package/dist/gesture-dispatch.js +106 -0
- package/dist/gesture-dispatch.js.map +1 -0
- package/dist/gestures.d.ts +23 -0
- package/dist/gestures.js +164 -0
- package/dist/gestures.js.map +1 -0
- package/dist/height-index.d.ts +31 -0
- package/dist/height-index.js +80 -0
- package/dist/height-index.js.map +1 -0
- package/dist/image-background.d.ts +32 -0
- package/dist/image-background.js +80 -0
- package/dist/image-background.js.map +1 -0
- package/dist/image.d.ts +79 -0
- package/dist/image.js +155 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/input-accessory-view.d.ts +16 -0
- package/dist/input-accessory-view.js +29 -0
- package/dist/input-accessory-view.js.map +1 -0
- package/dist/keyboard-avoiding-view.d.ts +79 -0
- package/dist/keyboard-avoiding-view.js +172 -0
- package/dist/keyboard-avoiding-view.js.map +1 -0
- package/dist/keyboard-dock.d.ts +126 -0
- package/dist/keyboard-dock.js +327 -0
- package/dist/keyboard-dock.js.map +1 -0
- package/dist/keyboard-taps.d.ts +12 -0
- package/dist/keyboard-taps.js +51 -0
- package/dist/keyboard-taps.js.map +1 -0
- package/dist/modal.d.ts +56 -0
- package/dist/modal.js +102 -0
- package/dist/modal.js.map +1 -0
- package/dist/native-gesture.d.ts +21 -0
- package/dist/native-gesture.js +56 -0
- package/dist/native-gesture.js.map +1 -0
- package/dist/native-ref.d.ts +7 -0
- package/dist/native-ref.js +13 -0
- package/dist/native-ref.js.map +1 -0
- package/dist/pressable.d.ts +220 -0
- package/dist/pressable.js +484 -0
- package/dist/pressable.js.map +1 -0
- package/dist/reanimated.d.ts +19 -0
- package/dist/reanimated.js +111 -0
- package/dist/reanimated.js.map +1 -0
- package/dist/refresh-control.d.ts +50 -0
- package/dist/refresh-control.js +103 -0
- package/dist/refresh-control.js.map +1 -0
- package/dist/safe-area-provider.d.ts +11 -0
- package/dist/safe-area-provider.js +70 -0
- package/dist/safe-area-provider.js.map +1 -0
- package/dist/safe-area-view.d.ts +22 -0
- package/dist/safe-area-view.js +77 -0
- package/dist/safe-area-view.js.map +1 -0
- package/dist/safe-area.d.ts +12 -0
- package/dist/safe-area.js +27 -0
- package/dist/safe-area.js.map +1 -0
- package/dist/scroll-view-props.d.ts +89 -0
- package/dist/scroll-view-props.js +153 -0
- package/dist/scroll-view-props.js.map +1 -0
- package/dist/scroll-view.d.ts +95 -0
- package/dist/scroll-view.js +181 -0
- package/dist/scroll-view.js.map +1 -0
- package/dist/section-list.d.ts +146 -0
- package/dist/section-list.js +300 -0
- package/dist/section-list.js.map +1 -0
- package/dist/sticky-headers.d.ts +41 -0
- package/dist/sticky-headers.js +118 -0
- package/dist/sticky-headers.js.map +1 -0
- package/dist/swipe-refresh-layout.d.ts +51 -0
- package/dist/swipe-refresh-layout.js +162 -0
- package/dist/swipe-refresh-layout.js.map +1 -0
- package/dist/switch.d.ts +54 -0
- package/dist/switch.js +110 -0
- package/dist/switch.js.map +1 -0
- package/dist/template-slot.d.ts +18 -0
- package/dist/template-slot.js +30 -0
- package/dist/template-slot.js.map +1 -0
- package/dist/text-input.d.ts +168 -0
- package/dist/text-input.js +312 -0
- package/dist/text-input.js.map +1 -0
- package/dist/text.d.ts +70 -0
- package/dist/text.js +111 -0
- package/dist/text.js.map +1 -0
- package/dist/touchable-opacity.d.ts +36 -0
- package/dist/touchable-opacity.js +76 -0
- package/dist/touchable-opacity.js.map +1 -0
- package/dist/transforms.d.ts +2 -0
- package/dist/transforms.js +17 -0
- package/dist/transforms.js.map +1 -0
- package/dist/view-base.d.ts +332 -0
- package/dist/view-base.js +534 -0
- package/dist/view-base.js.map +1 -0
- package/dist/view.d.ts +12 -0
- package/dist/view.js +18 -0
- package/dist/view.js.map +1 -0
- package/dist/virtual-list.d.ts +530 -0
- package/dist/virtual-list.js +1150 -0
- package/dist/virtual-list.js.map +1 -0
- package/dist/worklet-scroll.d.ts +13 -0
- package/dist/worklet-scroll.js +49 -0
- package/dist/worklet-scroll.js.map +1 -0
- package/dist/worklet-style.d.ts +13 -0
- package/dist/worklet-style.js +47 -0
- package/dist/worklet-style.js.map +1 -0
- package/dist/worklets.d.ts +89 -0
- package/dist/worklets.js +42 -0
- package/dist/worklets.js.map +1 -0
- package/dist/written-props.d.ts +6 -0
- package/dist/written-props.js +180 -0
- package/dist/written-props.js.map +1 -0
- package/package.json +88 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard-dock.js","sourceRoot":"","sources":["../src/keyboard-dock.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n DestroyRef,\n Directive,\n ElementRef,\n EnvironmentInjector,\n InjectionToken,\n afterRenderEffect,\n computed,\n contentChild,\n effect,\n inject,\n input,\n signal,\n untracked,\n type Provider,\n} from '@angular/core';\nimport { Keyboard, SCREEN_IN_FRONT, SafeArea } from '@ng-native/device';\nimport {\n claimHost,\n nativePlatform,\n registerViewName,\n type HostNode,\n type ScrollDrive,\n type ScrollRange,\n} from '@ng-native/fabric';\nimport { TemplateSlot } from './template-slot.ts';\nimport { TextInput } from './text-input.ts';\nimport { View } from './view.ts';\nimport { ViewBase } from './view-base.ts';\n\n/**\n * Whether react-native-keyboard-controller is installed, which is what lets a `<keyboard-dock>`\n * on iOS follow the keyboard frame by frame. See `provideKeyboardController`.\n */\nexport const KEYBOARD_CONTROLLER = new InjectionToken<boolean>('KEYBOARD_CONTROLLER', {\n providedIn: 'root',\n factory: () => false,\n});\n\n/**\n * Say that react-native-keyboard-controller is installed, for `<keyboard-dock>` to use on iOS.\n * Nothing is imported from it: the dock drives its native views directly.\n */\nexport function provideKeyboardController(): Provider {\n return { provide: KEYBOARD_CONTROLLER, useValue: true };\n}\n\n/** What carries the keyboard's height, frame by frame, in react-native-keyboard-controller. */\nconst KEYBOARD_FEED = {\n events: ['onKeyboardMove', 'onKeyboardMoveInteractive', 'onKeyboardMoveEnd'],\n path: ['height'],\n};\n\n/** Far enough that no keyboard is taller; native interpolation takes numbers, not infinity. */\nconst FAR = 10_000;\n\n/** A native view the dock renders for itself, out of the way of the layout. */\nconst OUT_OF_FLOW = { position: 'absolute', width: 0, height: 0 };\n\ntype KeyboardMoveEvent = { nativeEvent?: { height?: number } };\n\n/** react-native-keyboard-controller's view that reports the keyboard. See `KeyboardDock`. */\n@Directive({\n selector: 'keyboard-controller-view',\n host: { '[enabled]': 'true' },\n})\nexport class KeyboardControllerView {\n constructor() {\n registerViewName('keyboard-controller-view', 'KeyboardControllerView');\n claimHost(inject(ElementRef).nativeElement as HostNode);\n }\n}\n\n/**\n * react-native-keyboard-controller's drag area. On iOS it registers `offset` for the field with\n * `textInputNativeID`, so an interactive dismissal takes the keyboard from that far above it.\n */\n@Directive({\n selector: 'keyboard-gesture-area',\n host: { '[offset]': 'offset()', '[textInputNativeID]': 'textInputNativeID()' },\n})\nexport class KeyboardGestureArea {\n readonly offset = input<number>();\n readonly textInputNativeID = input<string>();\n\n constructor() {\n registerViewName('keyboard-gesture-area', 'KeyboardGestureArea');\n claimHost(inject(ElementRef).nativeElement as HostNode);\n }\n}\n\n/**\n * A bar that sits on the keyboard: a chat's composer, a comment box, a row of formatting keys.\n * At the bottom of its parent, clear of the home indicator or navigation bar, while the keyboard\n * is down; on top of it while it is up.\n *\n * On iOS with react-native-keyboard-controller (`provideKeyboardController()`), the bar is moved\n * by the keyboard's height on the native side, frame by frame, the way UIKit carries an input\n * accessory: as the keyboard rises and falls, and while a finger drags it down through a scroll\n * view with `keyboardDismissMode=\"interactive\"`, where iOS reports no keyboard frames to\n * JavaScript at all. The drag takes the keyboard from the top of the bar rather than the top of\n * the keyboard, as Messages does, and a short one springs it back up. `keyboardLift` moves\n * content above with it.\n *\n * Without it, and on Android, the bar is padded by as much of the keyboard as covers it, which it\n * learns as the keyboard starts to move; a window the system resized for the keyboard already\n * puts it clear, and then it is not padded at all.\n *\n * `covered()` is how much of the bottom of the screen the keyboard covers beyond the dock's own\n * place, for content above that keeps clear of it with padding or an inset rather than moving.\n */\n@Component({\n selector: 'keyboard-dock',\n exportAs: 'keyboardDock',\n imports: [KeyboardControllerView, KeyboardGestureArea, TemplateSlot, View],\n // One slot, stamped in whichever branch applies: two `<ng-content>`s of the same selector would\n // be given the content at compile time, whichever branch renders.\n template: `\n <ng-template #content><ng-content /></ng-template>\n @if (lifts) {\n <keyboard-controller-view\n [style]=\"outOfFlow\"\n (keyboardMoveStart)=\"onKeyboardMove($event)\"\n (keyboardMoveEnd)=\"onKeyboardMove($event)\"\n />\n <keyboard-gesture-area\n [style]=\"outOfFlow\"\n [offset]=\"barHeight()\"\n [textInputNativeID]=\"inputID()\"\n />\n <view\n collapsable=\"false\"\n [style.backgroundColor]=\"backgroundColor()\"\n (layout)=\"onBarLayout($event)\"\n ><ng-container [templateSlot]=\"content\" [templateSlotContext]=\"none\"\n /></view>\n } @else {\n <ng-container [templateSlot]=\"content\" [templateSlotContext]=\"none\" />\n }\n `,\n host: {\n '[style.paddingBottom]': 'padding()',\n '[style.backgroundColor]': 'backgroundColor()',\n '(layout)': 'onLayout()',\n },\n})\nexport class KeyboardDock extends ViewBase {\n /** The bar's background, under the inset it sits above as well as the bar itself. */\n readonly backgroundColor = input<string>();\n\n private readonly keyboard = inject(Keyboard);\n private readonly safeArea = inject(SafeArea);\n protected readonly none = {};\n protected readonly outOfFlow = OUT_OF_FLOW;\n\n /** iOS with the controller: native moves the bar. Read once: neither changes under an app. */\n protected readonly lifts = nativePlatform() === 'ios' && inject(KEYBOARD_CONTROLLER);\n\n private readonly field = contentChild(TextInput, { descendants: true, read: ElementRef });\n private readonly fieldInput = contentChild(TextInput, { descendants: true });\n\n /** Where the dock's bottom edge is in the window, which the keyboard is compared to. */\n private readonly bottomEdge = signal<number | null>(null);\n /** The bar's own height, measured, which the drag that lowers the keyboard starts above. */\n protected readonly barHeight = signal(0);\n /** The keyboard's height as the controller last reported it, excluding the drag area. */\n private readonly controlled = signal(0);\n\n /** The inset under the bar while the keyboard is down: the home indicator or navigation bar. */\n private readonly inset = computed(() => this.safeArea.insets().bottom);\n\n readonly covered = computed(() =>\n this.lifts ? Math.max(0, this.controlled() - this.inset()) : 0,\n );\n\n protected readonly padding = computed(() => {\n if (this.lifts) return this.inset();\n const { height, screenY } = this.keyboard.metrics();\n if (height === 0) return this.inset();\n const edge = this.bottomEdge();\n if (edge === null || screenY === undefined) return height;\n return Math.max(0, edge - screenY);\n });\n\n /**\n * The field the drag area belongs to, by `nativeID`, which the controller finds it by. A field\n * without one is given one.\n */\n protected readonly inputID = computed(() => {\n const input = this.fieldInput();\n const node = this.field()?.nativeElement as HostNode | undefined;\n if (!input || !node) return undefined;\n const own = input.nativeID() ?? input.id();\n if (own) return own;\n const id = `keyboard-dock-${++docks}`;\n untracked(() => this.engine.setProp(node, 'nativeID', id));\n return id;\n });\n\n /** The bar, and anything `keyboardLift` moves, rises by the keyboard less the inset under it. */\n readonly liftRange = computed<ScrollRange>(() => {\n const inset = this.inset();\n return { input: [inset, inset + FAR], output: [0, -FAR] };\n });\n\n private source: HostNode | null = null;\n\n private readonly inFront = inject(SCREEN_IN_FRONT);\n\n constructor() {\n super();\n if (this.lifts) this.liftBar();\n // A root effect, because a covered screen's views are detached from change detection, and a\n // view's own effects wait for it.\n const front = effect(\n () => {\n const inFront = this.inFront();\n untracked(() => {\n if (!inFront && this.keyboard.height() > 0) this.keyboard.dismiss();\n });\n },\n { injector: inject(EnvironmentInjector), manualCleanup: true },\n );\n inject(DestroyRef).onDestroy(() => front.destroy());\n }\n\n /**\n * Move a view with the keyboard on the native side, as the bar is moved: content above the bar\n * that should rise with it. Null when native does not move the bar. See `keyboardLift`.\n */\n lift(view: HostNode, shift: number | null = null): ScrollDrive | null {\n if (!this.lifts) return null;\n const source = this.controllerView();\n const range = this.liftRange();\n return this.engine.driveByEvent(view, source, KEYBOARD_FEED, 'translateY', range, [], shift);\n }\n\n private liftBar(): void {\n let drive: ScrollDrive | null = null;\n afterRenderEffect(() => {\n const range = this.liftRange();\n untracked(() => {\n if (drive) return drive.update(range);\n const bar = this.barView();\n if (bar) drive = this.lift(bar);\n });\n });\n inject(DestroyRef).onDestroy(() => drive?.stop());\n }\n\n /** The controller's view, the one whose events carry the keyboard. */\n private controllerView(): HostNode {\n this.source ??= this.node.children.find((child) => child.kind === 'element') ?? this.node;\n return this.source;\n }\n\n /** The view holding the content, the last of the dock's own. */\n private barView(): HostNode | undefined {\n return this.node.children.filter((child) => child.kind === 'element').at(-1);\n }\n\n protected onKeyboardMove(event: unknown): void {\n const height = (event as KeyboardMoveEvent).nativeEvent?.height;\n if (height !== undefined) this.controlled.set(height);\n }\n\n protected onBarLayout(event: { nativeEvent?: { layout?: { height?: number } } }): void {\n const height = event.nativeEvent?.layout?.height;\n if (height !== undefined) this.barHeight.set(height);\n }\n\n protected onLayout(): void {\n if (this.lifts) return;\n this.engine.measure(this.node, (frame) => this.bottomEdge.set(frame.y + frame.height));\n }\n}\n\nlet docks = 0;\n\n/**\n * Moves its view with a `<keyboard-dock>`'s bar: `<view [keyboardLift]=\"dock\">` around a chat's\n * transcript keeps the newest message on top of the bar as the keyboard rises, falls and is\n * dragged. Put it inside a view that clips, so what rises past the top is hidden rather than\n * drawn over what is above. Does nothing where native does not move the bar.\n *\n * Once the keyboard has moved, the view is padded by as much of it as covers the view, and moved\n * back down by the same amount, which leaves it where it was on screen: since iOS 26 a scroll view\n * the keyboard overlaps in layout draws a frosted edge effect over the part it thinks is covered,\n * and a transform does not change what it thinks.\n */\n@Directive({\n selector: '[keyboardLift]',\n host: { '[style.paddingBottom]': 'padding()' },\n})\nexport class KeyboardLift {\n readonly dock = input.required<KeyboardDock>({ alias: 'keyboardLift' });\n\n protected readonly padding = computed(() => {\n const covered = this.dock().covered();\n return covered > 0 ? covered : undefined;\n });\n\n constructor() {\n const view = inject(ElementRef).nativeElement as HostNode;\n let drive: ScrollDrive | null = null;\n afterRenderEffect(() => {\n const dock = this.dock();\n const range = dock.liftRange();\n const covered = dock.covered();\n untracked(() => {\n if (!drive) drive = dock.lift(view, covered);\n drive?.update(range);\n drive?.shift(covered);\n });\n });\n inject(DestroyRef).onDestroy(() => drive?.stop());\n }\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HostEngine, HostNode } from '@ng-native/fabric';
|
|
2
|
+
export type KeyboardShouldPersistTaps = 'always' | 'never' | 'handled';
|
|
3
|
+
/**
|
|
4
|
+
* What a tap in a scrolling container does while a text input has the keyboard up, which is
|
|
5
|
+
* `ScrollView.js`'s JavaScript in React Native rather than anything native. `never` (the default):
|
|
6
|
+
* a tap anywhere but on the input is the container's before a child sees it, and all it does is
|
|
7
|
+
* dismiss. `handled`: the child gets first refusal, and the tap dismisses only if nothing took it.
|
|
8
|
+
* `always`: the keyboard stays.
|
|
9
|
+
*
|
|
10
|
+
* Returns the responder's release, for the container's destroy.
|
|
11
|
+
*/
|
|
12
|
+
export declare function dismissKeyboardOnTap(engine: HostEngine, node: HostNode, policy: () => KeyboardShouldPersistTaps): () => void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a tap in a scrolling container does while a text input has the keyboard up, which is
|
|
3
|
+
* `ScrollView.js`'s JavaScript in React Native rather than anything native. `never` (the default):
|
|
4
|
+
* a tap anywhere but on the input is the container's before a child sees it, and all it does is
|
|
5
|
+
* dismiss. `handled`: the child gets first refusal, and the tap dismisses only if nothing took it.
|
|
6
|
+
* `always`: the keyboard stays.
|
|
7
|
+
*
|
|
8
|
+
* Returns the responder's release, for the container's destroy.
|
|
9
|
+
*/
|
|
10
|
+
export function dismissKeyboardOnTap(engine, node, policy) {
|
|
11
|
+
let dismissing = false;
|
|
12
|
+
/** A keyboard is up for an input, and the tap is not on that input. */
|
|
13
|
+
const tapDismisses = (target) => {
|
|
14
|
+
const focused = engine.focused;
|
|
15
|
+
if (!focused)
|
|
16
|
+
return false;
|
|
17
|
+
for (let at = target; at; at = at.parent) {
|
|
18
|
+
if (at === focused)
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
};
|
|
23
|
+
// RN's `_observedScrollSinceBecomingResponder`: a touch that scrolled was a drag, and a drag
|
|
24
|
+
// through the content is reading it, so its release leaves the keyboard up.
|
|
25
|
+
const stopScroll = engine.setEventListener(node, 'topScroll', () => {
|
|
26
|
+
dismissing = false;
|
|
27
|
+
});
|
|
28
|
+
const stopResponder = engine.setResponder(node, {
|
|
29
|
+
onStartShouldSetResponderCapture: (_, target) => policy() === 'never' && tapDismisses(target),
|
|
30
|
+
onStartShouldSetResponder: (_, target) => policy() === 'handled' && tapDismisses(target),
|
|
31
|
+
onResponderGrant: () => {
|
|
32
|
+
dismissing = true;
|
|
33
|
+
},
|
|
34
|
+
onResponderRelease: () => {
|
|
35
|
+
if (!dismissing)
|
|
36
|
+
return;
|
|
37
|
+
dismissing = false;
|
|
38
|
+
const focused = engine.focused;
|
|
39
|
+
if (focused)
|
|
40
|
+
engine.dispatchCommand(focused, 'blur');
|
|
41
|
+
},
|
|
42
|
+
onResponderTerminate: () => {
|
|
43
|
+
dismissing = false;
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
return () => {
|
|
47
|
+
stopScroll();
|
|
48
|
+
stopResponder();
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=keyboard-taps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard-taps.js","sourceRoot":"","sources":["../src/keyboard-taps.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAkB,EAClB,IAAc,EACd,MAAuC;IAEvC,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,uEAAuE;IACvE,MAAM,YAAY,GAAG,CAAC,MAAkB,EAAW,EAAE;QACnD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3B,KAAK,IAAI,EAAE,GAAsB,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;YAC5D,IAAI,EAAE,KAAK,OAAO;gBAAE,OAAO,KAAK,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,6FAA6F;IAC7F,4EAA4E;IAC5E,MAAM,UAAU,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;QACjE,UAAU,GAAG,KAAK,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE;QAC9C,gCAAgC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC;QAC7F,yBAAyB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,CAAC;QACxF,gBAAgB,EAAE,GAAG,EAAE;YACrB,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,kBAAkB,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,UAAU;gBAAE,OAAO;YACxB,UAAU,GAAG,KAAK,CAAC;YACnB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;YAC/B,IAAI,OAAO;gBAAE,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;QACD,oBAAoB,EAAE,GAAG,EAAE;YACzB,UAAU,GAAG,KAAK,CAAC;QACrB,CAAC;KACF,CAAC,CAAC;IACH,OAAO,GAAG,EAAE;QACV,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { EngineNode, HostEngine, HostNode } from '@ng-native/fabric';\n\nexport type KeyboardShouldPersistTaps = 'always' | 'never' | 'handled';\n\n/**\n * What a tap in a scrolling container does while a text input has the keyboard up, which is\n * `ScrollView.js`'s JavaScript in React Native rather than anything native. `never` (the default):\n * a tap anywhere but on the input is the container's before a child sees it, and all it does is\n * dismiss. `handled`: the child gets first refusal, and the tap dismisses only if nothing took it.\n * `always`: the keyboard stays.\n *\n * Returns the responder's release, for the container's destroy.\n */\nexport function dismissKeyboardOnTap(\n engine: HostEngine,\n node: HostNode,\n policy: () => KeyboardShouldPersistTaps,\n): () => void {\n let dismissing = false;\n\n /** A keyboard is up for an input, and the tap is not on that input. */\n const tapDismisses = (target: EngineNode): boolean => {\n const focused = engine.focused;\n if (!focused) return false;\n for (let at: EngineNode | null = target; at; at = at.parent) {\n if (at === focused) return false;\n }\n return true;\n };\n\n // RN's `_observedScrollSinceBecomingResponder`: a touch that scrolled was a drag, and a drag\n // through the content is reading it, so its release leaves the keyboard up.\n const stopScroll = engine.setEventListener(node, 'topScroll', () => {\n dismissing = false;\n });\n const stopResponder = engine.setResponder(node, {\n onStartShouldSetResponderCapture: (_, target) => policy() === 'never' && tapDismisses(target),\n onStartShouldSetResponder: (_, target) => policy() === 'handled' && tapDismisses(target),\n onResponderGrant: () => {\n dismissing = true;\n },\n onResponderRelease: () => {\n if (!dismissing) return;\n dismissing = false;\n const focused = engine.focused;\n if (focused) engine.dispatchCommand(focused, 'blur');\n },\n onResponderTerminate: () => {\n dismissing = false;\n },\n });\n return () => {\n stopScroll();\n stopResponder();\n };\n}\n"]}
|
package/dist/modal.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ViewBase } from './view-base.ts';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export type ModalPresentationStyle = 'fullScreen' | 'pageSheet' | 'formSheet' | 'overFullScreen';
|
|
4
|
+
export type ModalOrientation = 'portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right';
|
|
5
|
+
/**
|
|
6
|
+
* Content presented over everything else. Commits as `ModalHostView`.
|
|
7
|
+
*
|
|
8
|
+
* RN's `Modal.js` gives the native host `{position: 'absolute'}` (the engine's default for it)
|
|
9
|
+
* and puts the children inside a full-bleed view carrying the backdrop colour. Without the
|
|
10
|
+
* container the content has no backdrop and no layout box, so a modal renders as nothing.
|
|
11
|
+
*
|
|
12
|
+
* Events are element events: `(requestClose)` for the Android back button and an iOS swipe,
|
|
13
|
+
* `(show)`, `(dismiss)`, and `(orientationChange)`.
|
|
14
|
+
*
|
|
15
|
+
* The container is pinned to the leading edge with `[side]: 0`, the same as RN's own Modal.js -
|
|
16
|
+
* `left` in a left-to-right layout, `right` in a right-to-left one - so the backdrop starts from
|
|
17
|
+
* the edge content actually begins at rather than always the physical left.
|
|
18
|
+
*/
|
|
19
|
+
export declare class Modal extends ViewBase {
|
|
20
|
+
/**
|
|
21
|
+
* Whether the modal is showing. Defaults to true, as in RN. While false the engine leaves the
|
|
22
|
+
* native host out of the commit, as RN's Modal returns null when hidden, because the host
|
|
23
|
+
* covers the screen and takes every touch whether or not it presents; on iOS a modal that was
|
|
24
|
+
* showing stays until native reports its dismissal.
|
|
25
|
+
*/
|
|
26
|
+
readonly visible: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
27
|
+
/** See through to the screen behind; the container gets no backdrop. */
|
|
28
|
+
readonly transparent: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
29
|
+
/** The container's background when not transparent. Defaults to white. */
|
|
30
|
+
readonly backdropColor: import("@angular/core").InputSignal<string | undefined>;
|
|
31
|
+
/** How the modal appears and leaves. Defaults to `none`. */
|
|
32
|
+
readonly animationType: import("@angular/core").InputSignal<"none" | "slide" | "fade" | undefined>;
|
|
33
|
+
/** iOS: full screen, a sheet, or over the current content. `overFullScreen` if transparent. */
|
|
34
|
+
readonly presentationStyle: import("@angular/core").InputSignal<ModalPresentationStyle | undefined>;
|
|
35
|
+
/** iOS: which orientations the modal may rotate to. Defaults to portrait. */
|
|
36
|
+
readonly supportedOrientations: import("@angular/core").InputSignal<readonly ModalOrientation[] | undefined>;
|
|
37
|
+
/** iOS: let a downward swipe dismiss the modal, reported through `(requestClose)`. */
|
|
38
|
+
readonly allowSwipeDismissal: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
|
|
39
|
+
/** Android: draw under the status bar. */
|
|
40
|
+
readonly statusBarTranslucent: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
|
|
41
|
+
/** Android: draw under the navigation bar. Needs `statusBarTranslucent` too. */
|
|
42
|
+
readonly navigationBarTranslucent: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
|
|
43
|
+
/** Android: give the modal's window a hardware-accelerated surface. */
|
|
44
|
+
readonly hardwareAccelerated: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
|
|
45
|
+
private readonly direction;
|
|
46
|
+
protected readonly resolvedPresentationStyle: import("@angular/core").Signal<ModalPresentationStyle | undefined>;
|
|
47
|
+
protected readonly containerStyle: import("@angular/core").Signal<{
|
|
48
|
+
[x: string]: string | number;
|
|
49
|
+
top: number;
|
|
50
|
+
flex: number;
|
|
51
|
+
backgroundColor: string;
|
|
52
|
+
}>;
|
|
53
|
+
constructor();
|
|
54
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<Modal, never>;
|
|
55
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<Modal, "modal", never, { "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "transparent": { "alias": "transparent"; "required": false; "isSignal": true; }; "backdropColor": { "alias": "backdropColor"; "required": false; "isSignal": true; }; "animationType": { "alias": "animationType"; "required": false; "isSignal": true; }; "presentationStyle": { "alias": "presentationStyle"; "required": false; "isSignal": true; }; "supportedOrientations": { "alias": "supportedOrientations"; "required": false; "isSignal": true; }; "allowSwipeDismissal": { "alias": "allowSwipeDismissal"; "required": false; "isSignal": true; }; "statusBarTranslucent": { "alias": "statusBarTranslucent"; "required": false; "isSignal": true; }; "navigationBarTranslucent": { "alias": "navigationBarTranslucent"; "required": false; "isSignal": true; }; "hardwareAccelerated": { "alias": "hardwareAccelerated"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
56
|
+
}
|
package/dist/modal.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Component, DestroyRef, booleanAttribute, computed, effect, inject, input, } from '@angular/core';
|
|
2
|
+
import { Direction } from '@ng-native/device';
|
|
3
|
+
import { HostEngine } from '@ng-native/fabric';
|
|
4
|
+
import { optionalBoolean } from "./transforms.js";
|
|
5
|
+
import { View } from "./view.js";
|
|
6
|
+
import { ViewBase } from "./view-base.js";
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
/**
|
|
9
|
+
* Content presented over everything else. Commits as `ModalHostView`.
|
|
10
|
+
*
|
|
11
|
+
* RN's `Modal.js` gives the native host `{position: 'absolute'}` (the engine's default for it)
|
|
12
|
+
* and puts the children inside a full-bleed view carrying the backdrop colour. Without the
|
|
13
|
+
* container the content has no backdrop and no layout box, so a modal renders as nothing.
|
|
14
|
+
*
|
|
15
|
+
* Events are element events: `(requestClose)` for the Android back button and an iOS swipe,
|
|
16
|
+
* `(show)`, `(dismiss)`, and `(orientationChange)`.
|
|
17
|
+
*
|
|
18
|
+
* The container is pinned to the leading edge with `[side]: 0`, the same as RN's own Modal.js -
|
|
19
|
+
* `left` in a left-to-right layout, `right` in a right-to-left one - so the backdrop starts from
|
|
20
|
+
* the edge content actually begins at rather than always the physical left.
|
|
21
|
+
*/
|
|
22
|
+
export class Modal extends ViewBase {
|
|
23
|
+
/**
|
|
24
|
+
* Whether the modal is showing. Defaults to true, as in RN. While false the engine leaves the
|
|
25
|
+
* native host out of the commit, as RN's Modal returns null when hidden, because the host
|
|
26
|
+
* covers the screen and takes every touch whether or not it presents; on iOS a modal that was
|
|
27
|
+
* showing stays until native reports its dismissal.
|
|
28
|
+
*/
|
|
29
|
+
visible = input(true, { ...(ngDevMode ? { debugName: "visible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
30
|
+
/** See through to the screen behind; the container gets no backdrop. */
|
|
31
|
+
transparent = input(false, { ...(ngDevMode ? { debugName: "transparent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
32
|
+
/** The container's background when not transparent. Defaults to white. */
|
|
33
|
+
backdropColor = input(/* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [undefined, { debugName: "backdropColor" }] : /* istanbul ignore next */ []));
|
|
35
|
+
/** How the modal appears and leaves. Defaults to `none`. */
|
|
36
|
+
animationType = input(/* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [undefined, { debugName: "animationType" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/** iOS: full screen, a sheet, or over the current content. `overFullScreen` if transparent. */
|
|
39
|
+
presentationStyle = input(/* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [undefined, { debugName: "presentationStyle" }] : /* istanbul ignore next */ []));
|
|
41
|
+
/** iOS: which orientations the modal may rotate to. Defaults to portrait. */
|
|
42
|
+
supportedOrientations = input(/* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [undefined, { debugName: "supportedOrientations" }] : /* istanbul ignore next */ []));
|
|
44
|
+
/** iOS: let a downward swipe dismiss the modal, reported through `(requestClose)`. */
|
|
45
|
+
allowSwipeDismissal = input(undefined, { ...(ngDevMode ? { debugName: "allowSwipeDismissal" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
|
|
46
|
+
/** Android: draw under the status bar. */
|
|
47
|
+
statusBarTranslucent = input(undefined, { ...(ngDevMode ? { debugName: "statusBarTranslucent" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
|
|
48
|
+
/** Android: draw under the navigation bar. Needs `statusBarTranslucent` too. */
|
|
49
|
+
navigationBarTranslucent = input(undefined, { ...(ngDevMode ? { debugName: "navigationBarTranslucent" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
|
|
50
|
+
/** Android: give the modal's window a hardware-accelerated surface. */
|
|
51
|
+
hardwareAccelerated = input(undefined, { ...(ngDevMode ? { debugName: "hardwareAccelerated" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
|
|
52
|
+
direction = inject(Direction);
|
|
53
|
+
resolvedPresentationStyle = computed(() => this.presentationStyle() ?? (this.transparent() ? 'overFullScreen' : undefined), /* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [{ debugName: "resolvedPresentationStyle" }] : /* istanbul ignore next */ []));
|
|
55
|
+
containerStyle = computed(() => ({
|
|
56
|
+
[this.direction.rtl() ? 'right' : 'left']: 0,
|
|
57
|
+
top: 0,
|
|
58
|
+
flex: 1,
|
|
59
|
+
backgroundColor: this.transparent() ? 'transparent' : (this.backdropColor() ?? 'white'),
|
|
60
|
+
}), /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "containerStyle" }] : /* istanbul ignore next */ []));
|
|
62
|
+
constructor() {
|
|
63
|
+
super();
|
|
64
|
+
// RN's host claims any touch that reaches it, so nothing inside the modal can hand a
|
|
65
|
+
// gesture to the screen underneath.
|
|
66
|
+
const stop = inject(HostEngine).setResponder(this.node, {
|
|
67
|
+
onStartShouldSetResponder: () => true,
|
|
68
|
+
});
|
|
69
|
+
inject(DestroyRef).onDestroy(stop);
|
|
70
|
+
effect(() => {
|
|
71
|
+
const style = this.presentationStyle();
|
|
72
|
+
if (this.transparent() && style && style !== 'overFullScreen') {
|
|
73
|
+
console.warn(`[angular-native] <modal> is transparent, which needs presentationStyle="overFullScreen" on iOS; '${style}' will not be see-through.`);
|
|
74
|
+
}
|
|
75
|
+
if (this.navigationBarTranslucent() && !this.statusBarTranslucent()) {
|
|
76
|
+
console.warn('[angular-native] <modal> navigationBarTranslucent has no effect without statusBarTranslucent.');
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Modal, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
81
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: Modal, isStandalone: true, selector: "modal", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, transparent: { classPropertyName: "transparent", publicName: "transparent", isSignal: true, isRequired: false, transformFunction: null }, backdropColor: { classPropertyName: "backdropColor", publicName: "backdropColor", isSignal: true, isRequired: false, transformFunction: null }, animationType: { classPropertyName: "animationType", publicName: "animationType", isSignal: true, isRequired: false, transformFunction: null }, presentationStyle: { classPropertyName: "presentationStyle", publicName: "presentationStyle", isSignal: true, isRequired: false, transformFunction: null }, supportedOrientations: { classPropertyName: "supportedOrientations", publicName: "supportedOrientations", isSignal: true, isRequired: false, transformFunction: null }, allowSwipeDismissal: { classPropertyName: "allowSwipeDismissal", publicName: "allowSwipeDismissal", isSignal: true, isRequired: false, transformFunction: null }, statusBarTranslucent: { classPropertyName: "statusBarTranslucent", publicName: "statusBarTranslucent", isSignal: true, isRequired: false, transformFunction: null }, navigationBarTranslucent: { classPropertyName: "navigationBarTranslucent", publicName: "navigationBarTranslucent", isSignal: true, isRequired: false, transformFunction: null }, hardwareAccelerated: { classPropertyName: "hardwareAccelerated", publicName: "hardwareAccelerated", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "visible": "visible()", "transparent": "transparent()", "animationType": "animationType()", "presentationStyle": "resolvedPresentationStyle()", "supportedOrientations": "supportedOrientations()", "allowSwipeDismissal": "allowSwipeDismissal()", "statusBarTranslucent": "statusBarTranslucent()", "navigationBarTranslucent": "navigationBarTranslucent()", "hardwareAccelerated": "hardwareAccelerated()" } }, usesInheritance: true, ngImport: i0, template: `<view [style]="containerStyle()" collapsable="false"><ng-content /></view>`, isInline: true, dependencies: [{ kind: "directive", type: View, selector: "view" }] });
|
|
82
|
+
}
|
|
83
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Modal, decorators: [{
|
|
84
|
+
type: Component,
|
|
85
|
+
args: [{
|
|
86
|
+
selector: 'modal',
|
|
87
|
+
imports: [View],
|
|
88
|
+
template: `<view [style]="containerStyle()" collapsable="false"><ng-content /></view>`,
|
|
89
|
+
host: {
|
|
90
|
+
'[visible]': 'visible()',
|
|
91
|
+
'[transparent]': 'transparent()',
|
|
92
|
+
'[animationType]': 'animationType()',
|
|
93
|
+
'[presentationStyle]': 'resolvedPresentationStyle()',
|
|
94
|
+
'[supportedOrientations]': 'supportedOrientations()',
|
|
95
|
+
'[allowSwipeDismissal]': 'allowSwipeDismissal()',
|
|
96
|
+
'[statusBarTranslucent]': 'statusBarTranslucent()',
|
|
97
|
+
'[navigationBarTranslucent]': 'navigationBarTranslucent()',
|
|
98
|
+
'[hardwareAccelerated]': 'hardwareAccelerated()',
|
|
99
|
+
},
|
|
100
|
+
}]
|
|
101
|
+
}], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], transparent: [{ type: i0.Input, args: [{ isSignal: true, alias: "transparent", required: false }] }], backdropColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropColor", required: false }] }], animationType: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationType", required: false }] }], presentationStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentationStyle", required: false }] }], supportedOrientations: [{ type: i0.Input, args: [{ isSignal: true, alias: "supportedOrientations", required: false }] }], allowSwipeDismissal: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowSwipeDismissal", required: false }] }], statusBarTranslucent: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusBarTranslucent", required: false }] }], navigationBarTranslucent: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigationBarTranslucent", required: false }] }], hardwareAccelerated: [{ type: i0.Input, args: [{ isSignal: true, alias: "hardwareAccelerated", required: false }] }] } });
|
|
102
|
+
//# sourceMappingURL=modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modal.js","sourceRoot":"","sources":["../src/modal.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n DestroyRef,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n} from '@angular/core';\nimport { Direction } from '@ng-native/device';\nimport { HostEngine } from '@ng-native/fabric';\nimport { optionalBoolean } from './transforms.ts';\nimport { View } from './view.ts';\nimport { ViewBase } from './view-base.ts';\n\nexport type ModalPresentationStyle = 'fullScreen' | 'pageSheet' | 'formSheet' | 'overFullScreen';\nexport type ModalOrientation =\n 'portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right';\n\n/**\n * Content presented over everything else. Commits as `ModalHostView`.\n *\n * RN's `Modal.js` gives the native host `{position: 'absolute'}` (the engine's default for it)\n * and puts the children inside a full-bleed view carrying the backdrop colour. Without the\n * container the content has no backdrop and no layout box, so a modal renders as nothing.\n *\n * Events are element events: `(requestClose)` for the Android back button and an iOS swipe,\n * `(show)`, `(dismiss)`, and `(orientationChange)`.\n *\n * The container is pinned to the leading edge with `[side]: 0`, the same as RN's own Modal.js -\n * `left` in a left-to-right layout, `right` in a right-to-left one - so the backdrop starts from\n * the edge content actually begins at rather than always the physical left.\n */\n@Component({\n selector: 'modal',\n imports: [View],\n template: `<view [style]=\"containerStyle()\" collapsable=\"false\"><ng-content /></view>`,\n host: {\n '[visible]': 'visible()',\n '[transparent]': 'transparent()',\n '[animationType]': 'animationType()',\n '[presentationStyle]': 'resolvedPresentationStyle()',\n '[supportedOrientations]': 'supportedOrientations()',\n '[allowSwipeDismissal]': 'allowSwipeDismissal()',\n '[statusBarTranslucent]': 'statusBarTranslucent()',\n '[navigationBarTranslucent]': 'navigationBarTranslucent()',\n '[hardwareAccelerated]': 'hardwareAccelerated()',\n },\n})\nexport class Modal extends ViewBase {\n /**\n * Whether the modal is showing. Defaults to true, as in RN. While false the engine leaves the\n * native host out of the commit, as RN's Modal returns null when hidden, because the host\n * covers the screen and takes every touch whether or not it presents; on iOS a modal that was\n * showing stays until native reports its dismissal.\n */\n readonly visible = input(true, { transform: booleanAttribute });\n /** See through to the screen behind; the container gets no backdrop. */\n readonly transparent = input(false, { transform: booleanAttribute });\n /** The container's background when not transparent. Defaults to white. */\n readonly backdropColor = input<string>();\n /** How the modal appears and leaves. Defaults to `none`. */\n readonly animationType = input<'none' | 'slide' | 'fade'>();\n /** iOS: full screen, a sheet, or over the current content. `overFullScreen` if transparent. */\n readonly presentationStyle = input<ModalPresentationStyle>();\n /** iOS: which orientations the modal may rotate to. Defaults to portrait. */\n readonly supportedOrientations = input<readonly ModalOrientation[]>();\n /** iOS: let a downward swipe dismiss the modal, reported through `(requestClose)`. */\n readonly allowSwipeDismissal = input(undefined, { transform: optionalBoolean });\n /** Android: draw under the status bar. */\n readonly statusBarTranslucent = input(undefined, { transform: optionalBoolean });\n /** Android: draw under the navigation bar. Needs `statusBarTranslucent` too. */\n readonly navigationBarTranslucent = input(undefined, { transform: optionalBoolean });\n /** Android: give the modal's window a hardware-accelerated surface. */\n readonly hardwareAccelerated = input(undefined, { transform: optionalBoolean });\n\n private readonly direction = inject(Direction);\n\n protected readonly resolvedPresentationStyle = computed(\n () => this.presentationStyle() ?? (this.transparent() ? 'overFullScreen' : undefined),\n );\n\n protected readonly containerStyle = computed(() => ({\n [this.direction.rtl() ? 'right' : 'left']: 0,\n top: 0,\n flex: 1,\n backgroundColor: this.transparent() ? 'transparent' : (this.backdropColor() ?? 'white'),\n }));\n\n constructor() {\n super();\n // RN's host claims any touch that reaches it, so nothing inside the modal can hand a\n // gesture to the screen underneath.\n const stop = inject(HostEngine).setResponder(this.node, {\n onStartShouldSetResponder: () => true,\n });\n inject(DestroyRef).onDestroy(stop);\n\n effect(() => {\n const style = this.presentationStyle();\n if (this.transparent() && style && style !== 'overFullScreen') {\n console.warn(\n `[angular-native] <modal> is transparent, which needs presentationStyle=\"overFullScreen\" on iOS; '${style}' will not be see-through.`,\n );\n }\n if (this.navigationBarTranslucent() && !this.statusBarTranslucent()) {\n console.warn(\n '[angular-native] <modal> navigationBarTranslucent has no effect without statusBarTranslucent.',\n );\n }\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
/**
|
|
3
|
+
* The behaviour, with the library left as a dependency so a test can drive a fake one.
|
|
4
|
+
*
|
|
5
|
+
* `collapsable` is the load-bearing part of the host bindings. Native attaches a recogniser to a
|
|
6
|
+
* *view*, and a view that only groups its children can be collapsed away by the renderer, leaving
|
|
7
|
+
* a tag that resolves to nothing; the library retries a few times and then gives up silently, so
|
|
8
|
+
* the gesture simply never fires. `GestureDetector` avoids it by cloning its child with
|
|
9
|
+
* `collapsable: false`, and this is that, as a host binding. It runs after the host component's
|
|
10
|
+
* own binding for the same prop, which is what makes it win.
|
|
11
|
+
*/
|
|
12
|
+
export declare class NativeGestureBase {
|
|
13
|
+
private readonly node;
|
|
14
|
+
private readonly engine;
|
|
15
|
+
private readonly gestures;
|
|
16
|
+
private readonly injector;
|
|
17
|
+
readonly gesture: import("@angular/core").InputSignal<object>;
|
|
18
|
+
constructor();
|
|
19
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NativeGestureBase, never>;
|
|
20
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NativeGestureBase, "[gesture]", never, { "gesture": { "alias": "gesture"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A native gesture, attached to the element it sits on.
|
|
3
|
+
*
|
|
4
|
+
* ```html
|
|
5
|
+
* <view [gesture]="pan">
|
|
6
|
+
* ```
|
|
7
|
+
*
|
|
8
|
+
* The equivalent of `GestureDetector`, which is a React component whose whole job is to hold a
|
|
9
|
+
* ref, turn it into a view tag, and hand that tag to the native module. A directive already has
|
|
10
|
+
* the node, and the engine already knows its tag.
|
|
11
|
+
*
|
|
12
|
+
* `NativeGesture` in `../gestures.ts` is the one apps import: same selector, and it supplies the
|
|
13
|
+
* real library itself.
|
|
14
|
+
*/
|
|
15
|
+
import { Directive, ElementRef, Injector, afterNextRender, effect, inject, input, } from '@angular/core';
|
|
16
|
+
import { Engine } from '@ng-native/fabric';
|
|
17
|
+
import { GESTURES } from "./gesture-backend.js";
|
|
18
|
+
import * as i0 from "@angular/core";
|
|
19
|
+
/**
|
|
20
|
+
* The behaviour, with the library left as a dependency so a test can drive a fake one.
|
|
21
|
+
*
|
|
22
|
+
* `collapsable` is the load-bearing part of the host bindings. Native attaches a recogniser to a
|
|
23
|
+
* *view*, and a view that only groups its children can be collapsed away by the renderer, leaving
|
|
24
|
+
* a tag that resolves to nothing; the library retries a few times and then gives up silently, so
|
|
25
|
+
* the gesture simply never fires. `GestureDetector` avoids it by cloning its child with
|
|
26
|
+
* `collapsable: false`, and this is that, as a host binding. It runs after the host component's
|
|
27
|
+
* own binding for the same prop, which is what makes it win.
|
|
28
|
+
*/
|
|
29
|
+
export class NativeGestureBase {
|
|
30
|
+
node = inject(ElementRef).nativeElement;
|
|
31
|
+
engine = inject(Engine);
|
|
32
|
+
gestures = inject(GESTURES);
|
|
33
|
+
injector = inject(Injector);
|
|
34
|
+
gesture = input.required(/* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "gesture" }] : /* istanbul ignore next */ []));
|
|
36
|
+
constructor() {
|
|
37
|
+
// Native attaches a recogniser to a view, so there has to be one: a node has no react tag
|
|
38
|
+
// until it has been committed.
|
|
39
|
+
afterNextRender(() => {
|
|
40
|
+
effect((onCleanup) => {
|
|
41
|
+
const gesture = this.gesture();
|
|
42
|
+
const tag = this.engine.tagOf(this.node);
|
|
43
|
+
if (tag === null)
|
|
44
|
+
return;
|
|
45
|
+
onCleanup(this.gestures.attach({ tag }, gesture));
|
|
46
|
+
}, { injector: this.injector });
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeGestureBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
50
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: NativeGestureBase, isStandalone: true, selector: "[gesture]", inputs: { gesture: { classPropertyName: "gesture", publicName: "gesture", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "collapsable": "false" } }, ngImport: i0 });
|
|
51
|
+
}
|
|
52
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeGestureBase, decorators: [{
|
|
53
|
+
type: Directive,
|
|
54
|
+
args: [{ selector: '[gesture]', host: { '[collapsable]': 'false' } }]
|
|
55
|
+
}], ctorParameters: () => [], propDecorators: { gesture: [{ type: i0.Input, args: [{ isSignal: true, alias: "gesture", required: true }] }] } });
|
|
56
|
+
//# sourceMappingURL=native-gesture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-gesture.js","sourceRoot":"","sources":["../src/native-gesture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,eAAe,EACf,MAAM,EACN,MAAM,EACN,KAAK,GACN,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAmB,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAoB,MAAM,sBAAsB,CAAC;;AAElE;;;;;;;;;GASG;AAEH,MAAM,OAAO,iBAAiB;IACX,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,aAA2B,CAAC;IACtD,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEpC,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAe,CAAC;IAEjD;QACE,0FAA0F;QAC1F,+BAA+B;QAC/B,eAAe,CAAC,GAAG,EAAE;YACnB,MAAM,CACJ,CAAC,SAAS,EAAE,EAAE;gBACZ,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzC,IAAI,GAAG,KAAK,IAAI;oBAAE,OAAO;gBACzB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YACpD,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAC5B,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;uGAtBU,iBAAiB;2FAAjB,iBAAiB;;2FAAjB,iBAAiB;kBAD7B,SAAS;mBAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE","sourcesContent":["/**\n * A native gesture, attached to the element it sits on.\n *\n * ```html\n * <view [gesture]=\"pan\">\n * ```\n *\n * The equivalent of `GestureDetector`, which is a React component whose whole job is to hold a\n * ref, turn it into a view tag, and hand that tag to the native module. A directive already has\n * the node, and the engine already knows its tag.\n *\n * `NativeGesture` in `../gestures.ts` is the one apps import: same selector, and it supplies the\n * real library itself.\n */\nimport {\n Directive,\n ElementRef,\n Injector,\n afterNextRender,\n effect,\n inject,\n input,\n} from '@angular/core';\nimport { Engine, type EngineNode } from '@ng-native/fabric';\nimport { GESTURES, type GestureSpec } from './gesture-backend.ts';\n\n/**\n * The behaviour, with the library left as a dependency so a test can drive a fake one.\n *\n * `collapsable` is the load-bearing part of the host bindings. Native attaches a recogniser to a\n * *view*, and a view that only groups its children can be collapsed away by the renderer, leaving\n * a tag that resolves to nothing; the library retries a few times and then gives up silently, so\n * the gesture simply never fires. `GestureDetector` avoids it by cloning its child with\n * `collapsable: false`, and this is that, as a host binding. It runs after the host component's\n * own binding for the same prop, which is what makes it win.\n */\n@Directive({ selector: '[gesture]', host: { '[collapsable]': 'false' } })\nexport class NativeGestureBase {\n private readonly node = inject(ElementRef).nativeElement as EngineNode;\n private readonly engine = inject(Engine);\n private readonly gestures = inject(GESTURES);\n private readonly injector = inject(Injector);\n\n readonly gesture = input.required<GestureSpec>();\n\n constructor() {\n // Native attaches a recogniser to a view, so there has to be one: a node has no react tag\n // until it has been committed.\n afterNextRender(() => {\n effect(\n (onCleanup) => {\n const gesture = this.gesture();\n const tag = this.engine.tagOf(this.node);\n if (tag === null) return;\n onCleanup(this.gestures.attach({ tag }, gesture));\n },\n { injector: this.injector },\n );\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
/** Escape hatch for reading a primitive's retained node, e.g. to issue a native command. */
|
|
3
|
+
export declare class NativeRef {
|
|
4
|
+
readonly node: any;
|
|
5
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NativeRef, never>;
|
|
6
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NativeRef, "[nativeRef]", ["nativeRef"], {}, {}, never, never, true, never>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Directive, ElementRef, inject } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/** Escape hatch for reading a primitive's retained node, e.g. to issue a native command. */
|
|
4
|
+
export class NativeRef {
|
|
5
|
+
node = inject(ElementRef).nativeElement;
|
|
6
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeRef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
7
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: NativeRef, isStandalone: true, selector: "[nativeRef]", exportAs: ["nativeRef"], ngImport: i0 });
|
|
8
|
+
}
|
|
9
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeRef, decorators: [{
|
|
10
|
+
type: Directive,
|
|
11
|
+
args: [{ selector: '[nativeRef]', exportAs: 'nativeRef' }]
|
|
12
|
+
}] });
|
|
13
|
+
//# sourceMappingURL=native-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-ref.js","sourceRoot":"","sources":["../src/native-ref.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAE9D,4FAA4F;AAE5F,MAAM,OAAO,SAAS;IACX,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC;uGADtC,SAAS;2FAAT,SAAS;;2FAAT,SAAS;kBADrB,SAAS;mBAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE","sourcesContent":["import { Directive, ElementRef, inject } from '@angular/core';\n\n/** Escape hatch for reading a primitive's retained node, e.g. to issue a native command. */\n@Directive({ selector: '[nativeRef]', exportAs: 'nativeRef' })\nexport class NativeRef {\n readonly node = inject(ElementRef).nativeElement;\n}\n"]}
|