@symbiote-native/angular 0.8.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -10
- package/babel-register-composed.cjs +58 -18
- package/bin/symbiote-angular-dev.cjs +16 -4
- package/build/angular/anchor-host-registry.js +1 -15
- package/build/angular/anchor-host-registry.js.map +1 -1
- package/build/angular/change-detection-flush.d.ts +31 -0
- package/build/angular/change-detection-flush.js +110 -0
- package/build/angular/change-detection-flush.js.map +1 -0
- package/build/angular/components/activity-indicator-props.d.ts +2 -0
- package/build/angular/components/activity-indicator-props.js +2 -0
- package/build/angular/components/activity-indicator-props.js.map +1 -0
- package/build/angular/components/button-props.d.ts +2 -0
- package/build/angular/components/button-props.js +2 -0
- package/build/angular/components/button-props.js.map +1 -0
- package/build/angular/components/flat-list/index.d.ts +2 -1
- package/build/angular/components/flat-list/index.js +22 -10
- package/build/angular/components/flat-list/index.js.map +1 -1
- package/build/angular/components/image-background-props.d.ts +6 -0
- package/build/angular/components/image-background-props.js +2 -0
- package/build/angular/components/image-background-props.js.map +1 -0
- package/build/angular/components/{image/shared.d.ts → image-shared.d.ts} +4 -4
- package/build/angular/components/{image/shared.js → image-shared.js} +39 -28
- package/build/angular/components/image-shared.js.map +1 -0
- package/build/angular/components/input-accessory-view-props.d.ts +7 -0
- package/build/angular/components/input-accessory-view-props.js +9 -0
- package/build/angular/components/input-accessory-view-props.js.map +1 -0
- package/build/angular/components/keyboard-avoiding-view/index.d.ts +2 -1
- package/build/angular/components/keyboard-avoiding-view/index.js +28 -27
- package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
- package/build/angular/components/modal/index.d.ts +2 -0
- package/build/angular/components/modal/index.js +33 -20
- package/build/angular/components/modal/index.js.map +1 -1
- package/build/angular/components/pressable-props.d.ts +32 -0
- package/build/angular/components/pressable-props.js +11 -0
- package/build/angular/components/pressable-props.js.map +1 -0
- package/build/angular/components/refresh-control-props.d.ts +16 -0
- package/build/angular/components/refresh-control-props.js +14 -0
- package/build/angular/components/refresh-control-props.js.map +1 -0
- package/build/angular/components/safe-area-view-props.d.ts +7 -0
- package/build/angular/components/safe-area-view-props.js +11 -0
- package/build/angular/components/safe-area-view-props.js.map +1 -0
- package/build/angular/components/scroll-view-props.d.ts +76 -0
- package/build/angular/components/scroll-view-props.js +18 -0
- package/build/angular/components/scroll-view-props.js.map +1 -0
- package/build/angular/components/section-list/index.d.ts +3 -0
- package/build/angular/components/section-list/index.js +10 -1
- package/build/angular/components/section-list/index.js.map +1 -1
- package/build/angular/components/text-input-props.d.ts +45 -0
- package/build/angular/components/text-input-props.js +18 -0
- package/build/angular/components/text-input-props.js.map +1 -0
- package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.d.ts +6 -0
- package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.js +2 -0
- package/build/angular/components/touchable-native-feedback/touchable-native-feedback-props.js.map +1 -0
- package/build/angular/components/touchable-props.d.ts +14 -0
- package/build/angular/components/touchable-props.js +13 -0
- package/build/angular/components/touchable-props.js.map +1 -0
- package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.d.ts +3 -0
- package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.js +2 -0
- package/build/angular/components/touchable-without-feedback/touchable-without-feedback-props.js.map +1 -0
- package/build/angular/components/virtualized-list/index.d.ts +8 -1
- package/build/angular/components/virtualized-list/index.js +373 -278
- package/build/angular/components/virtualized-list/index.js.map +1 -1
- package/build/angular/components/virtualized-section-list/index.d.ts +3 -0
- package/build/angular/components/virtualized-section-list/index.js +10 -1
- package/build/angular/components/virtualized-section-list/index.js.map +1 -1
- package/build/angular/components.d.ts +21 -27
- package/build/angular/components.js +13 -15
- package/build/angular/components.js.map +1 -1
- package/build/angular/create-portal/index.d.ts +11 -2
- package/build/angular/create-portal/index.js +37 -11
- package/build/angular/create-portal/index.js.map +1 -1
- package/build/angular/create-tunnel/index.js +1 -1
- package/build/angular/element-props.d.ts +53 -0
- package/build/angular/element-props.js +2 -0
- package/build/angular/element-props.js.map +1 -0
- package/build/angular/elements.d.ts +528 -0
- package/build/angular/elements.js +1444 -0
- package/build/angular/elements.js.map +1 -0
- package/build/angular/gate-demand.d.ts +37 -0
- package/build/angular/gate-demand.js +84 -0
- package/build/angular/gate-demand.js.map +1 -0
- package/build/angular/host-instance/index.js +1 -1
- package/build/angular/index.d.ts +5 -2
- package/build/angular/index.js +16 -1
- package/build/angular/index.js.map +1 -1
- package/build/angular/modules/animated/create-animated-component.d.ts +6 -6
- package/build/angular/modules/animated/create-animated-component.js +73 -81
- package/build/angular/modules/animated/create-animated-component.js.map +1 -1
- package/build/angular/modules/animated/index.js +1 -1
- package/build/angular/modules/animated/index.js.map +1 -1
- package/build/angular/modules/image/index.d.ts +3 -0
- package/build/angular/modules/image/index.js +16 -0
- package/build/angular/modules/image/index.js.map +1 -0
- package/build/angular/primitives/index.d.ts +28 -16
- package/build/angular/primitives/index.js +77 -31
- package/build/angular/primitives/index.js.map +1 -1
- package/build/angular/primitives/shared.d.ts +2 -3
- package/build/angular/primitives/shared.js +8 -53
- package/build/angular/primitives/shared.js.map +1 -1
- package/build/angular/register.d.ts +1 -0
- package/build/angular/register.js +16 -0
- package/build/angular/register.js.map +1 -0
- package/build/angular/render/index.js +4 -2
- package/build/angular/render/index.js.map +1 -1
- package/build/angular/renderer/index.js +207 -60
- package/build/angular/renderer/index.js.map +1 -1
- package/build/angular/renderer/value-change.d.ts +2 -0
- package/build/angular/renderer/value-change.js +9 -0
- package/build/angular/renderer/value-change.js.map +1 -0
- package/metro-config.cjs +23 -5
- package/metro-css-parser.cjs +2 -1
- package/package.json +17 -7
- package/src/anchor-host-registry.ts +1 -15
- package/src/change-detection-flush.ts +120 -0
- package/src/components/activity-indicator-props.ts +21 -0
- package/src/components/button-props.ts +26 -0
- package/src/components/flat-list/index.ts +12 -4
- package/src/components/image-background-props.ts +24 -0
- package/src/components/{image/shared.ts → image-shared.ts} +57 -26
- package/src/components/input-accessory-view-props.ts +21 -0
- package/src/components/keyboard-avoiding-view/index.ts +27 -16
- package/src/components/modal/index.ts +32 -11
- package/src/components/pressable-props.ts +73 -0
- package/src/components/refresh-control-props.ts +43 -0
- package/src/components/safe-area-view-props.ts +28 -0
- package/src/components/scroll-view-props.ts +109 -0
- package/src/components/section-list/index.ts +18 -0
- package/src/components/text-input-props.ts +72 -0
- package/src/components/touchable-native-feedback/touchable-native-feedback-props.ts +23 -0
- package/src/components/touchable-props.ts +30 -0
- package/src/components/touchable-without-feedback/touchable-without-feedback-props.ts +21 -0
- package/src/components/virtualized-list/index.ts +254 -153
- package/src/components/virtualized-section-list/index.ts +18 -0
- package/src/components.ts +86 -35
- package/src/create-portal/index.ts +39 -9
- package/src/create-tunnel/index.ts +1 -1
- package/src/diagnostics.ts +1 -1
- package/src/element-props.ts +90 -0
- package/src/elements.ts +919 -0
- package/src/gate-demand.ts +109 -0
- package/src/host-instance/index.ts +1 -1
- package/src/index.ts +54 -15
- package/src/modules/animated/create-animated-component.ts +73 -59
- package/src/modules/animated/index.ts +1 -1
- package/src/modules/image/index.ts +18 -0
- package/src/primitives/index.ts +47 -16
- package/src/primitives/shared.ts +11 -44
- package/src/register.ts +15 -0
- package/src/render/index.ts +4 -2
- package/src/renderer/index.ts +239 -80
- package/src/renderer/value-change.ts +8 -0
- package/build/angular/components/activity-indicator/index.android.d.ts +0 -13
- package/build/angular/components/activity-indicator/index.android.js +0 -29
- package/build/angular/components/activity-indicator/index.android.js.map +0 -1
- package/build/angular/components/activity-indicator/index.d.ts +0 -1
- package/build/angular/components/activity-indicator/index.ios.d.ts +0 -9
- package/build/angular/components/activity-indicator/index.ios.js +0 -26
- package/build/angular/components/activity-indicator/index.ios.js.map +0 -1
- package/build/angular/components/activity-indicator/index.js +0 -4
- package/build/angular/components/activity-indicator/index.js.map +0 -1
- package/build/angular/components/activity-indicator/shared.d.ts +0 -67
- package/build/angular/components/activity-indicator/shared.js +0 -260
- package/build/angular/components/activity-indicator/shared.js.map +0 -1
- package/build/angular/components/button.d.ts +0 -65
- package/build/angular/components/button.js +0 -351
- package/build/angular/components/button.js.map +0 -1
- package/build/angular/components/image/index.android.d.ts +0 -15
- package/build/angular/components/image/index.android.js +0 -91
- package/build/angular/components/image/index.android.js.map +0 -1
- package/build/angular/components/image/index.d.ts +0 -1
- package/build/angular/components/image/index.ios.d.ts +0 -15
- package/build/angular/components/image/index.ios.js +0 -91
- package/build/angular/components/image/index.ios.js.map +0 -1
- package/build/angular/components/image/index.js +0 -3
- package/build/angular/components/image/index.js.map +0 -1
- package/build/angular/components/image/shared.js.map +0 -1
- package/build/angular/components/image-background.d.ts +0 -82
- package/build/angular/components/image-background.js +0 -434
- package/build/angular/components/image-background.js.map +0 -1
- package/build/angular/components/input-accessory-view/index.d.ts +0 -65
- package/build/angular/components/input-accessory-view/index.js +0 -290
- package/build/angular/components/input-accessory-view/index.js.map +0 -1
- package/build/angular/components/pressable/index.d.ts +0 -129
- package/build/angular/components/pressable/index.js +0 -473
- package/build/angular/components/pressable/index.js.map +0 -1
- package/build/angular/components/refresh-control/index.d.ts +0 -90
- package/build/angular/components/refresh-control/index.js +0 -380
- package/build/angular/components/refresh-control/index.js.map +0 -1
- package/build/angular/components/safe-area-view/index.d.ts +0 -62
- package/build/angular/components/safe-area-view/index.js +0 -287
- package/build/angular/components/safe-area-view/index.js.map +0 -1
- package/build/angular/components/scroll-view/index.android.d.ts +0 -20
- package/build/angular/components/scroll-view/index.android.js +0 -262
- package/build/angular/components/scroll-view/index.android.js.map +0 -1
- package/build/angular/components/scroll-view/index.d.ts +0 -3
- package/build/angular/components/scroll-view/index.ios.d.ts +0 -8
- package/build/angular/components/scroll-view/index.ios.js +0 -92
- package/build/angular/components/scroll-view/index.ios.js.map +0 -1
- package/build/angular/components/scroll-view/index.js +0 -6
- package/build/angular/components/scroll-view/index.js.map +0 -1
- package/build/angular/components/scroll-view/projection.d.ts +0 -67
- package/build/angular/components/scroll-view/projection.js +0 -560
- package/build/angular/components/scroll-view/projection.js.map +0 -1
- package/build/angular/components/scroll-view/shared.d.ts +0 -239
- package/build/angular/components/scroll-view/shared.js +0 -832
- package/build/angular/components/scroll-view/shared.js.map +0 -1
- package/build/angular/components/scroll-view/sticky-header.d.ts +0 -40
- package/build/angular/components/scroll-view/sticky-header.js +0 -224
- package/build/angular/components/scroll-view/sticky-header.js.map +0 -1
- package/build/angular/components/switch/index.android.d.ts +0 -24
- package/build/angular/components/switch/index.android.js +0 -112
- package/build/angular/components/switch/index.android.js.map +0 -1
- package/build/angular/components/switch/index.d.ts +0 -1
- package/build/angular/components/switch/index.ios.d.ts +0 -23
- package/build/angular/components/switch/index.ios.js +0 -111
- package/build/angular/components/switch/index.ios.js.map +0 -1
- package/build/angular/components/switch/index.js +0 -4
- package/build/angular/components/switch/index.js.map +0 -1
- package/build/angular/components/switch/shared.d.ts +0 -49
- package/build/angular/components/switch/shared.js +0 -191
- package/build/angular/components/switch/shared.js.map +0 -1
- package/build/angular/components/text-input.d.ts +0 -161
- package/build/angular/components/text-input.js +0 -659
- package/build/angular/components/text-input.js.map +0 -1
- package/build/angular/components/touchable/index.d.ts +0 -276
- package/build/angular/components/touchable/index.js +0 -1422
- package/build/angular/components/touchable/index.js.map +0 -1
- package/build/angular/components/touchable-native-feedback/index.d.ts +0 -86
- package/build/angular/components/touchable-native-feedback/index.js +0 -407
- package/build/angular/components/touchable-native-feedback/index.js.map +0 -1
- package/src/components/activity-indicator/index.android.ts +0 -23
- package/src/components/activity-indicator/index.ios.ts +0 -21
- package/src/components/activity-indicator/index.ts +0 -4
- package/src/components/activity-indicator/shared.ts +0 -225
- package/src/components/button.ts +0 -220
- package/src/components/image/index.android.ts +0 -99
- package/src/components/image/index.ios.ts +0 -99
- package/src/components/image/index.ts +0 -3
- package/src/components/image-background.ts +0 -290
- package/src/components/input-accessory-view/index.ts +0 -240
- package/src/components/pressable/index.ts +0 -462
- package/src/components/refresh-control/index.ts +0 -340
- package/src/components/safe-area-view/index.ts +0 -231
- package/src/components/scroll-view/index.android.ts +0 -205
- package/src/components/scroll-view/index.ios.ts +0 -81
- package/src/components/scroll-view/index.ts +0 -7
- package/src/components/scroll-view/projection.ts +0 -713
- package/src/components/scroll-view/shared.ts +0 -1066
- package/src/components/scroll-view/sticky-header.ts +0 -267
- package/src/components/switch/index.android.ts +0 -113
- package/src/components/switch/index.ios.ts +0 -112
- package/src/components/switch/index.ts +0 -4
- package/src/components/switch/shared.ts +0 -284
- package/src/components/text-input.ts +0 -613
- package/src/components/touchable/index.ts +0 -913
- package/src/components/touchable-native-feedback/index.ts +0 -317
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CUSTOM_ELEMENTS_SCHEMA,
|
|
3
|
-
ChangeDetectionStrategy,
|
|
4
|
-
ChangeDetectorRef,
|
|
5
|
-
Component,
|
|
6
|
-
ElementRef,
|
|
7
|
-
EventEmitter,
|
|
8
|
-
computed,
|
|
9
|
-
inject,
|
|
10
|
-
Input,
|
|
11
|
-
Output,
|
|
12
|
-
signal,
|
|
13
|
-
ViewChild,
|
|
14
|
-
type DoCheck,
|
|
15
|
-
type OnChanges,
|
|
16
|
-
} from '@angular/core';
|
|
17
|
-
import {
|
|
18
|
-
createPressHandlers,
|
|
19
|
-
createPressRuntime,
|
|
20
|
-
DEFAULT_DELAY_LONG_PRESS_MS,
|
|
21
|
-
isTerminationAllowed,
|
|
22
|
-
resolveAccessibilityProps,
|
|
23
|
-
resolveDisabledAccessibilityState,
|
|
24
|
-
rippleProps,
|
|
25
|
-
shouldClaimResponder,
|
|
26
|
-
shouldSuppressPress,
|
|
27
|
-
type IAccessibilityProps,
|
|
28
|
-
type IAccessibilityStateValue,
|
|
29
|
-
type IAriaProps,
|
|
30
|
-
type IPressableAndroidRippleConfig,
|
|
31
|
-
type IPressHandler,
|
|
32
|
-
type IPressHost,
|
|
33
|
-
type IPressMachineConfig,
|
|
34
|
-
type IPressRuntime,
|
|
35
|
-
type IPressState,
|
|
36
|
-
type IRectOffset,
|
|
37
|
-
} from '@symbiote-native/components';
|
|
38
|
-
import {
|
|
39
|
-
dlog,
|
|
40
|
-
isSymbioteNode,
|
|
41
|
-
measure,
|
|
42
|
-
type ISymbioteEvent,
|
|
43
|
-
type ISymbioteNode,
|
|
44
|
-
type IStyleProp,
|
|
45
|
-
type IViewStyle,
|
|
46
|
-
} from '@symbiote-native/engine';
|
|
47
|
-
import {
|
|
48
|
-
anchorHostStyle,
|
|
49
|
-
SymbioteHostPropsDirective,
|
|
50
|
-
SymbioteStyleInputDirective,
|
|
51
|
-
ViewHost,
|
|
52
|
-
} from '../../primitives';
|
|
53
|
-
|
|
54
|
-
export type {
|
|
55
|
-
IPressState,
|
|
56
|
-
IPressableAndroidRippleConfig,
|
|
57
|
-
} from '@symbiote-native/components';
|
|
58
|
-
|
|
59
|
-
// The full logical Pressable surface, callback-shaped press/hover events included. Touchable* and
|
|
60
|
-
// TouchableNativeFeedback still take their OWN onPress/onPressIn/... as @Input() callbacks (that is
|
|
61
|
-
// a separate, not-yet-converted decision) and derive their public prop types from this - so it keeps
|
|
62
|
-
// the callback fields even though the Pressable component below no longer implements them directly.
|
|
63
|
-
export interface IAngularPressableProps
|
|
64
|
-
extends IAccessibilityProps, IAriaProps {
|
|
65
|
-
onPress?: IPressHandler;
|
|
66
|
-
onPressIn?: IPressHandler;
|
|
67
|
-
onPressOut?: IPressHandler;
|
|
68
|
-
onPressMove?: IPressHandler;
|
|
69
|
-
onLongPress?: IPressHandler;
|
|
70
|
-
delayLongPress?: number;
|
|
71
|
-
disabled?: boolean;
|
|
72
|
-
cancelable?: boolean;
|
|
73
|
-
hitSlop?: IRectOffset;
|
|
74
|
-
pressRetentionOffset?: IRectOffset;
|
|
75
|
-
unstable_pressDelay?: number;
|
|
76
|
-
android_ripple?: IPressableAndroidRippleConfig;
|
|
77
|
-
android_disableSound?: boolean;
|
|
78
|
-
onHoverIn?: IPressHandler;
|
|
79
|
-
onHoverOut?: IPressHandler;
|
|
80
|
-
delayHoverIn?: number;
|
|
81
|
-
delayHoverOut?: number;
|
|
82
|
-
testID?: string;
|
|
83
|
-
nativeID?: string;
|
|
84
|
-
hasTVPreferredFocus?: boolean;
|
|
85
|
-
nextFocusDown?: number;
|
|
86
|
-
nextFocusForward?: number;
|
|
87
|
-
nextFocusLeft?: number;
|
|
88
|
-
nextFocusRight?: number;
|
|
89
|
-
nextFocusUp?: number;
|
|
90
|
-
style?:
|
|
91
|
-
IStyleProp<IViewStyle> | ((state: IPressState) => IStyleProp<IViewStyle>);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// What the Pressable component itself takes as plain @Input()s: the full surface minus the press/
|
|
95
|
-
// hover events and the four accessibility callbacks, all of which it exposes as real @Output()
|
|
96
|
-
// EventEmitters instead (see the class below) - the one place in the family where the
|
|
97
|
-
// callback-vs-EventEmitter tradeoff is actually fixed.
|
|
98
|
-
export type IAngularPressableInputs = Omit<
|
|
99
|
-
IAngularPressableProps,
|
|
100
|
-
| 'onPress'
|
|
101
|
-
| 'onPressIn'
|
|
102
|
-
| 'onPressOut'
|
|
103
|
-
| 'onPressMove'
|
|
104
|
-
| 'onLongPress'
|
|
105
|
-
| 'onHoverIn'
|
|
106
|
-
| 'onHoverOut'
|
|
107
|
-
| 'onAccessibilityAction'
|
|
108
|
-
| 'onAccessibilityTap'
|
|
109
|
-
| 'onMagicTap'
|
|
110
|
-
| 'onAccessibilityEscape'
|
|
111
|
-
>;
|
|
112
|
-
|
|
113
|
-
function isStyleFn(
|
|
114
|
-
value: unknown,
|
|
115
|
-
): value is (state: IPressState) => IStyleProp<IViewStyle> {
|
|
116
|
-
return typeof value === 'function';
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function asSymbioteEvent(event: unknown): ISymbioteEvent | undefined {
|
|
120
|
-
return typeof event === 'object' && event !== null && 'nativeEvent' in event
|
|
121
|
-
? (event as ISymbioteEvent)
|
|
122
|
-
: undefined;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
@Component({
|
|
126
|
-
selector: 'Pressable, symbiote-pressable',
|
|
127
|
-
standalone: true,
|
|
128
|
-
hostDirectives: [
|
|
129
|
-
{ directive: SymbioteStyleInputDirective, inputs: ['style'] },
|
|
130
|
-
],
|
|
131
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
132
|
-
imports: [ViewHost, SymbioteHostPropsDirective],
|
|
133
|
-
template: `
|
|
134
|
-
<symbiote-view
|
|
135
|
-
#host
|
|
136
|
-
[symbioteHostProps]="hostProps()"
|
|
137
|
-
(accessibilityAction)="emit(accessibilityAction, $event)"
|
|
138
|
-
(accessibilityTap)="emit(accessibilityTap, $event)"
|
|
139
|
-
(magicTap)="emit(magicTap, $event)"
|
|
140
|
-
(accessibilityEscape)="emit(accessibilityEscape, $event)"
|
|
141
|
-
(press)="handlePress($event)"
|
|
142
|
-
(pressIn)="handlePressIn($event)"
|
|
143
|
-
(pressOut)="handlePressOut($event)"
|
|
144
|
-
(responderMove)="handleResponderMove($event)"
|
|
145
|
-
(startShouldSetResponder)="claimResponder()"
|
|
146
|
-
(responderTerminationRequest)="allowTermination()"
|
|
147
|
-
>
|
|
148
|
-
<ng-content></ng-content>
|
|
149
|
-
</symbiote-view>
|
|
150
|
-
`,
|
|
151
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
152
|
-
})
|
|
153
|
-
export class Pressable implements IAngularPressableInputs, OnChanges, DoCheck {
|
|
154
|
-
// The press/hover lifecycle as real Angular events: `(press)="onTap($event)"`, not
|
|
155
|
-
// `[onPress]="onTap"`. createPressHandlers still wants plain IPressHandler callbacks, so
|
|
156
|
-
// emitterHandler() below adapts each EventEmitter into one - only while something is actually
|
|
157
|
-
// subscribed (`.observed`), so an unbound onLongPress still skips arming the timer, exactly as
|
|
158
|
-
// the old @Input()-absent case did.
|
|
159
|
-
@Output() readonly press = new EventEmitter<ISymbioteEvent>();
|
|
160
|
-
@Output() readonly pressIn = new EventEmitter<ISymbioteEvent>();
|
|
161
|
-
@Output() readonly pressOut = new EventEmitter<ISymbioteEvent>();
|
|
162
|
-
@Output() readonly pressMove = new EventEmitter<ISymbioteEvent>();
|
|
163
|
-
@Output() readonly longPress = new EventEmitter<ISymbioteEvent>();
|
|
164
|
-
@Output() readonly hoverIn = new EventEmitter<ISymbioteEvent>();
|
|
165
|
-
@Output() readonly hoverOut = new EventEmitter<ISymbioteEvent>();
|
|
166
|
-
// The four accessibility callbacks as real Angular events too, same tradeoff as press/hover
|
|
167
|
-
// above: `(accessibilityAction)="emit(accessibilityAction, $event)"`, not
|
|
168
|
-
// `[onAccessibilityAction]="onAccessibilityAction"`.
|
|
169
|
-
@Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
|
|
170
|
-
@Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
|
|
171
|
-
@Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
|
|
172
|
-
@Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
|
|
173
|
-
@Input() delayLongPress?: number;
|
|
174
|
-
@Input() disabled?: boolean;
|
|
175
|
-
@Input() cancelable?: boolean;
|
|
176
|
-
@Input() hitSlop?: IRectOffset;
|
|
177
|
-
@Input() pressRetentionOffset?: IRectOffset;
|
|
178
|
-
@Input() unstable_pressDelay?: number;
|
|
179
|
-
@Input() android_ripple?: IPressableAndroidRippleConfig;
|
|
180
|
-
@Input() android_disableSound?: boolean;
|
|
181
|
-
@Input() delayHoverIn?: number;
|
|
182
|
-
@Input() delayHoverOut?: number;
|
|
183
|
-
@Input() testID?: string;
|
|
184
|
-
@Input() nativeID?: string;
|
|
185
|
-
@Input() hasTVPreferredFocus?: boolean;
|
|
186
|
-
@Input() nextFocusDown?: number;
|
|
187
|
-
@Input() nextFocusForward?: number;
|
|
188
|
-
@Input() nextFocusLeft?: number;
|
|
189
|
-
@Input() nextFocusRight?: number;
|
|
190
|
-
@Input() nextFocusUp?: number;
|
|
191
|
-
@Input() style?: IAngularPressableProps['style'];
|
|
192
|
-
@Input() accessible?: boolean;
|
|
193
|
-
@Input() accessibilityLabel?: string;
|
|
194
|
-
@Input() accessibilityHint?: string;
|
|
195
|
-
@Input() accessibilityRole?: IAngularPressableProps['accessibilityRole'];
|
|
196
|
-
@Input() accessibilityState?: IAccessibilityStateValue;
|
|
197
|
-
@Input() accessibilityValue?: IAngularPressableProps['accessibilityValue'];
|
|
198
|
-
@Input()
|
|
199
|
-
accessibilityActions?: IAngularPressableProps['accessibilityActions'];
|
|
200
|
-
@Input() accessibilityLabelledBy?: string | string[];
|
|
201
|
-
@Input()
|
|
202
|
-
importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
203
|
-
@Input()
|
|
204
|
-
accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
205
|
-
@Input() screenReaderFocusable?: boolean;
|
|
206
|
-
@Input() accessibilityViewIsModal?: boolean;
|
|
207
|
-
@Input() accessibilityElementsHidden?: boolean;
|
|
208
|
-
@Input() accessibilityIgnoresInvertColors?: boolean;
|
|
209
|
-
@Input() accessibilityLanguage?: string;
|
|
210
|
-
@Input() accessibilityRespondsToUserInteraction?: boolean;
|
|
211
|
-
@Input() accessibilityShowsLargeContentViewer?: boolean;
|
|
212
|
-
@Input() accessibilityLargeContentTitle?: string;
|
|
213
|
-
@Input() ariaLabel?: string;
|
|
214
|
-
@Input() ariaBusy?: boolean;
|
|
215
|
-
@Input() ariaChecked?: boolean | 'mixed';
|
|
216
|
-
@Input() ariaDisabled?: boolean;
|
|
217
|
-
@Input() ariaExpanded?: boolean;
|
|
218
|
-
@Input() ariaHidden?: boolean;
|
|
219
|
-
@Input() ariaLabelledBy?: string;
|
|
220
|
-
@Input() ariaLive?: IAriaProps['aria-live'];
|
|
221
|
-
@Input() ariaSelected?: boolean;
|
|
222
|
-
@Input() ariaModal?: boolean;
|
|
223
|
-
@Input() ariaValueMax?: number;
|
|
224
|
-
@Input() ariaValueMin?: number;
|
|
225
|
-
@Input() ariaValueNow?: number;
|
|
226
|
-
@Input() ariaValueText?: string;
|
|
227
|
-
@Input() id?: string;
|
|
228
|
-
@Input() role?: IAngularPressableProps['role'];
|
|
229
|
-
|
|
230
|
-
@ViewChild('host', { read: ElementRef })
|
|
231
|
-
private hostElement?: ElementRef<unknown>;
|
|
232
|
-
|
|
233
|
-
// INTERNAL mutable state, driven by the press machine rather than by an @Input, so ngOnChanges
|
|
234
|
-
// can never cover it - it carries its OWN signal, which is what lets the memoized bag below stay
|
|
235
|
-
// correct across a press. Exposed as a plain boolean getter so a use site's `#ref.pressed` keeps
|
|
236
|
-
// reading a boolean and the public surface is unchanged.
|
|
237
|
-
private readonly pressedState = signal(false);
|
|
238
|
-
|
|
239
|
-
get pressed(): boolean {
|
|
240
|
-
return this.pressedState();
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
private readonly runtime: IPressRuntime = createPressRuntime();
|
|
244
|
-
private readonly host: IPressHost = {
|
|
245
|
-
setPressed: pressed => {
|
|
246
|
-
this.pressedState.set(pressed);
|
|
247
|
-
this.changeDetector.detectChanges();
|
|
248
|
-
},
|
|
249
|
-
getMeasureFn: () => {
|
|
250
|
-
const node = this.hostNode;
|
|
251
|
-
if (node === undefined) return undefined;
|
|
252
|
-
return callback => measure(node, callback);
|
|
253
|
-
},
|
|
254
|
-
schedule: (callback, ms) => {
|
|
255
|
-
const id = setTimeout(callback, ms);
|
|
256
|
-
return () => clearTimeout(id);
|
|
257
|
-
},
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
private readonly changeDetector = inject(ChangeDetectorRef);
|
|
261
|
-
// This component's OWN host - the non-painting anchor `class="..."` at the use site resolves
|
|
262
|
-
// onto (see anchorHostStyle's doc comment) - NOT `hostElement` above, which targets the real
|
|
263
|
-
// inner `symbiote-view` one level down.
|
|
264
|
-
private readonly elementRef = inject(ElementRef);
|
|
265
|
-
|
|
266
|
-
// Bridges the non-reactive @Input fields above into the reactive graph, so the computed() bag
|
|
267
|
-
// below can memoize a value derived from them. Signal inputs would make this unnecessary, but
|
|
268
|
-
// `input()` is visible only to the AOT compiler and this package's unit suite runs on JIT - see
|
|
269
|
-
// the `angular-adapter-change-detection` skill, §6. Mirrors ScrollView's identical bridge
|
|
270
|
-
// (components/scroll-view/shared.ts), including its constraint: ONLY safe for a bag whose every
|
|
271
|
-
// dependency is an @Input or carries its own signal, never for plain internal mutable state.
|
|
272
|
-
private readonly inputsRevision = signal(0);
|
|
273
|
-
|
|
274
|
-
// The anchor's class-derived style is the one hostProps dependency that is NOT an @Input:
|
|
275
|
-
// `class="..."`/`[class.x]`/`[ngClass]` at the use site resolves through the renderer's
|
|
276
|
-
// addClass/removeClass onto the anchor node (anchorHostStyle's doc comment), so it never appears
|
|
277
|
-
// in SimpleChanges and ngOnChanges cannot cover it. The engine's commitClassStyle allocates a
|
|
278
|
-
// fresh [classStyle, explicitStyle] array on exactly the passes where a class token actually
|
|
279
|
-
// moved, so signal.set's own Object.is check makes an unchanged poll a no-op that dirties nothing.
|
|
280
|
-
private readonly anchorStyle = signal<unknown>(undefined);
|
|
281
|
-
|
|
282
|
-
// ngDoCheck is the only hook that observes the anchor AFTER the parent wrote it. Angular flushes
|
|
283
|
-
// a node's pre-order hooks at the next `advance` PAST it (hooks.ts callHooks runs "until that
|
|
284
|
-
// node index exclusive") or in refreshView's post-template flush - both strictly after the
|
|
285
|
-
// parent's classProp on this element, and strictly before this component's own view refreshes.
|
|
286
|
-
// Angular also nulls the active consumer around lifecycle hooks (render3/hooks.ts), so this
|
|
287
|
-
// write registers no dependency on the caller's view and cannot throw NG0600.
|
|
288
|
-
ngDoCheck(): void {
|
|
289
|
-
this.anchorStyle.set(anchorHostStyle(this.elementRef));
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
ngOnChanges(): void {
|
|
293
|
-
// Tells the computed bag below that an @Input moved - plain class fields are not reactive on
|
|
294
|
-
// their own. Must stay in ngOnChanges: that is the single moment Angular has finished writing
|
|
295
|
-
// every changed input for this pass.
|
|
296
|
-
this.inputsRevision.update(revision => revision + 1);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
get resolvedStyle(): IStyleProp<IViewStyle> | undefined {
|
|
300
|
-
const state: IPressState = { pressed: this.pressed };
|
|
301
|
-
return isStyleFn(this.style) ? this.style(state) : this.style;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
get foldedAccessibility(): Partial<IAngularPressableProps> {
|
|
305
|
-
return resolveAccessibilityProps({
|
|
306
|
-
accessibilityLabel: this.accessibilityLabel,
|
|
307
|
-
accessibilityHint: this.accessibilityHint,
|
|
308
|
-
accessibilityRole: this.accessibilityRole,
|
|
309
|
-
accessibilityState: resolveDisabledAccessibilityState(
|
|
310
|
-
this.accessibilityState,
|
|
311
|
-
this.disabled,
|
|
312
|
-
),
|
|
313
|
-
accessibilityValue: this.accessibilityValue,
|
|
314
|
-
accessibilityActions: this.accessibilityActions,
|
|
315
|
-
accessibilityLabelledBy: this.accessibilityLabelledBy,
|
|
316
|
-
importantForAccessibility: this.importantForAccessibility,
|
|
317
|
-
accessibilityLiveRegion: this.accessibilityLiveRegion,
|
|
318
|
-
screenReaderFocusable: this.screenReaderFocusable,
|
|
319
|
-
accessibilityViewIsModal: this.accessibilityViewIsModal,
|
|
320
|
-
accessibilityElementsHidden: this.accessibilityElementsHidden,
|
|
321
|
-
accessibilityIgnoresInvertColors: this.accessibilityIgnoresInvertColors,
|
|
322
|
-
accessibilityLanguage: this.accessibilityLanguage,
|
|
323
|
-
accessibilityRespondsToUserInteraction:
|
|
324
|
-
this.accessibilityRespondsToUserInteraction,
|
|
325
|
-
accessibilityShowsLargeContentViewer:
|
|
326
|
-
this.accessibilityShowsLargeContentViewer,
|
|
327
|
-
accessibilityLargeContentTitle: this.accessibilityLargeContentTitle,
|
|
328
|
-
'aria-label': this.ariaLabel,
|
|
329
|
-
'aria-busy': this.ariaBusy,
|
|
330
|
-
'aria-checked': this.ariaChecked,
|
|
331
|
-
'aria-disabled': this.ariaDisabled,
|
|
332
|
-
'aria-expanded': this.ariaExpanded,
|
|
333
|
-
'aria-hidden': this.ariaHidden,
|
|
334
|
-
'aria-labelledby': this.ariaLabelledBy,
|
|
335
|
-
'aria-live': this.ariaLive,
|
|
336
|
-
'aria-selected': this.ariaSelected,
|
|
337
|
-
'aria-modal': this.ariaModal,
|
|
338
|
-
'aria-valuemax': this.ariaValueMax,
|
|
339
|
-
'aria-valuemin': this.ariaValueMin,
|
|
340
|
-
'aria-valuenow': this.ariaValueNow,
|
|
341
|
-
'aria-valuetext': this.ariaValueText,
|
|
342
|
-
id: this.id,
|
|
343
|
-
role: this.role,
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
get resolvedRippleProps(): Record<string, unknown> | undefined {
|
|
348
|
-
return this.android_ripple === undefined
|
|
349
|
-
? undefined
|
|
350
|
-
: rippleProps(this.android_ripple);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Flat bag for `[symbioteHostProps]` (Renderer2.setProperty per key) - see primitives/shared.ts.
|
|
354
|
-
//
|
|
355
|
-
// MEASURED 2026-08-16: as a getter this rebuilt the bag on every refresh of this view, and a
|
|
356
|
-
// press dirties this very view (SymbioteHostPropsDirective wraps each flat-bag onX with
|
|
357
|
-
// markForCheck, and setPressed calls detectChanges outright), so `[symbioteHostProps]`'s
|
|
358
|
-
// reference check failed every time and re-pushed every key through Renderer2.setProperty ->
|
|
359
|
-
// routeProp for an identical bag. Memoized, an unchanged bag costs one reference compare.
|
|
360
|
-
readonly hostProps = computed<Record<string, unknown>>(() => {
|
|
361
|
-
this.inputsRevision();
|
|
362
|
-
return {
|
|
363
|
-
testID: this.testID,
|
|
364
|
-
nativeID: this.nativeID,
|
|
365
|
-
hasTVPreferredFocus: this.hasTVPreferredFocus,
|
|
366
|
-
nextFocusDown: this.nextFocusDown,
|
|
367
|
-
nextFocusForward: this.nextFocusForward,
|
|
368
|
-
nextFocusLeft: this.nextFocusLeft,
|
|
369
|
-
nextFocusRight: this.nextFocusRight,
|
|
370
|
-
nextFocusUp: this.nextFocusUp,
|
|
371
|
-
style: [this.anchorStyle(), this.resolvedStyle],
|
|
372
|
-
accessible: this.accessible,
|
|
373
|
-
...this.foldedAccessibility,
|
|
374
|
-
android_disableSound: this.android_disableSound,
|
|
375
|
-
nativeBackgroundAndroid:
|
|
376
|
-
this.resolvedRippleProps?.nativeBackgroundAndroid,
|
|
377
|
-
nativeForegroundAndroid:
|
|
378
|
-
this.resolvedRippleProps?.nativeForegroundAndroid,
|
|
379
|
-
};
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
handlePressIn(event: unknown): void {
|
|
383
|
-
const symbioteEvent = asSymbioteEvent(event);
|
|
384
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
385
|
-
return;
|
|
386
|
-
this.handlers.handlePressIn(symbioteEvent);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
handlePressOut(event: unknown): void {
|
|
390
|
-
const symbioteEvent = asSymbioteEvent(event);
|
|
391
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
392
|
-
return;
|
|
393
|
-
this.handlers.handlePressOut(symbioteEvent);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
handlePress(event: unknown): void {
|
|
397
|
-
const symbioteEvent = asSymbioteEvent(event);
|
|
398
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
399
|
-
return;
|
|
400
|
-
this.handlers.handlePress(symbioteEvent);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
handleResponderMove(event: unknown): void {
|
|
404
|
-
const symbioteEvent = asSymbioteEvent(event);
|
|
405
|
-
if (shouldSuppressPress(this.disabled) || symbioteEvent === undefined)
|
|
406
|
-
return;
|
|
407
|
-
this.handlers.handleResponderMove(symbioteEvent);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
claimResponder(): boolean {
|
|
411
|
-
return shouldClaimResponder(this.disabled);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
allowTermination(): boolean {
|
|
415
|
-
return isTerminationAllowed(this.cancelable);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
emit(emitter: EventEmitter<ISymbioteEvent>, event: unknown): void {
|
|
419
|
-
const symbioteEvent = asSymbioteEvent(event);
|
|
420
|
-
if (symbioteEvent !== undefined) emitter.emit(symbioteEvent);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// Hover has no event on a touch host (no pointer-enter/leave); this only records that someone
|
|
424
|
-
// is listening anyway, mirroring core's noteHoverNoop but off `.observed` instead of an @Input.
|
|
425
|
-
private noteHoverNoop(): void {
|
|
426
|
-
if (this.hoverIn.observed || this.hoverOut.observed) {
|
|
427
|
-
dlog(
|
|
428
|
-
'Pressable hover is a no-op on this host (no pointer-enter/leave event)',
|
|
429
|
-
);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// Wraps an @Output() as an IPressHandler only while it has a subscriber, so an unbound
|
|
434
|
-
// (longPress) still skips arming the timer, matching createPressHandlers' "undefined means
|
|
435
|
-
// nobody cares" contract.
|
|
436
|
-
private emitterHandler(
|
|
437
|
-
emitter: EventEmitter<ISymbioteEvent>,
|
|
438
|
-
): IPressHandler | undefined {
|
|
439
|
-
return emitter.observed ? event => emitter.emit(event) : undefined;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
private get handlers() {
|
|
443
|
-
this.noteHoverNoop();
|
|
444
|
-
const config: IPressMachineConfig = {
|
|
445
|
-
onPress: this.emitterHandler(this.press),
|
|
446
|
-
onPressIn: this.emitterHandler(this.pressIn),
|
|
447
|
-
onPressOut: this.emitterHandler(this.pressOut),
|
|
448
|
-
onPressMove: this.emitterHandler(this.pressMove),
|
|
449
|
-
onLongPress: this.emitterHandler(this.longPress),
|
|
450
|
-
delayLongPress: this.delayLongPress ?? DEFAULT_DELAY_LONG_PRESS_MS,
|
|
451
|
-
unstable_pressDelay: this.unstable_pressDelay ?? 0,
|
|
452
|
-
hitSlop: this.hitSlop,
|
|
453
|
-
pressRetentionOffset: this.pressRetentionOffset,
|
|
454
|
-
};
|
|
455
|
-
return createPressHandlers(config, this.runtime, this.host);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
private get hostNode(): ISymbioteNode | undefined {
|
|
459
|
-
const native = this.hostElement?.nativeElement;
|
|
460
|
-
return isSymbioteNode(native) ? native : undefined;
|
|
461
|
-
}
|
|
462
|
-
}
|