@symbiote-native/angular 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +147 -0
- package/build/angular/components/activity-indicator/index.android.d.ts +12 -0
- package/build/angular/components/activity-indicator/index.android.js +21 -0
- package/build/angular/components/activity-indicator/index.android.js.map +1 -0
- package/build/angular/components/activity-indicator/index.d.ts +1 -0
- package/build/angular/components/activity-indicator/index.ios.d.ts +8 -0
- package/build/angular/components/activity-indicator/index.ios.js +21 -0
- package/build/angular/components/activity-indicator/index.ios.js.map +1 -0
- package/build/angular/components/activity-indicator/index.js +4 -0
- package/build/angular/components/activity-indicator/index.js.map +1 -0
- package/build/angular/components/activity-indicator/shared.d.ts +67 -0
- package/build/angular/components/activity-indicator/shared.js +260 -0
- package/build/angular/components/activity-indicator/shared.js.map +1 -0
- package/build/angular/components/button.d.ts +63 -0
- package/build/angular/components/button.js +332 -0
- package/build/angular/components/button.js.map +1 -0
- package/build/angular/components/drawer-layout-android/index.android.d.ts +34 -0
- package/build/angular/components/drawer-layout-android/index.android.js +291 -0
- package/build/angular/components/drawer-layout-android/index.android.js.map +1 -0
- package/build/angular/components/drawer-layout-android/index.d.ts +11 -0
- package/build/angular/components/drawer-layout-android/index.js +109 -0
- package/build/angular/components/drawer-layout-android/index.js.map +1 -0
- package/build/angular/components/drawer-layout-android/shared.d.ts +74 -0
- package/build/angular/components/drawer-layout-android/shared.js +138 -0
- package/build/angular/components/drawer-layout-android/shared.js.map +1 -0
- package/build/angular/components/flat-list/index.d.ts +122 -0
- package/build/angular/components/flat-list/index.js +689 -0
- package/build/angular/components/flat-list/index.js.map +1 -0
- package/build/angular/components/image/index.android.d.ts +10 -0
- package/build/angular/components/image/index.android.js +59 -0
- package/build/angular/components/image/index.android.js.map +1 -0
- package/build/angular/components/image/index.d.ts +1 -0
- package/build/angular/components/image/index.ios.d.ts +10 -0
- package/build/angular/components/image/index.ios.js +59 -0
- package/build/angular/components/image/index.ios.js.map +1 -0
- package/build/angular/components/image/index.js +3 -0
- package/build/angular/components/image/index.js.map +1 -0
- package/build/angular/components/image/shared.d.ts +101 -0
- package/build/angular/components/image/shared.js +408 -0
- package/build/angular/components/image/shared.js.map +1 -0
- package/build/angular/components/image-background.d.ts +81 -0
- package/build/angular/components/image-background.js +418 -0
- package/build/angular/components/image-background.js.map +1 -0
- package/build/angular/components/input-accessory-view.d.ts +59 -0
- package/build/angular/components/input-accessory-view.js +266 -0
- package/build/angular/components/input-accessory-view.js.map +1 -0
- package/build/angular/components/keyboard-avoiding-view.d.ts +82 -0
- package/build/angular/components/keyboard-avoiding-view.js +363 -0
- package/build/angular/components/keyboard-avoiding-view.js.map +1 -0
- package/build/angular/components/modal.d.ts +92 -0
- package/build/angular/components/modal.js +365 -0
- package/build/angular/components/modal.js.map +1 -0
- package/build/angular/components/pressable/index.d.ts +123 -0
- package/build/angular/components/pressable/index.js +421 -0
- package/build/angular/components/pressable/index.js.map +1 -0
- package/build/angular/components/refresh-control.d.ts +86 -0
- package/build/angular/components/refresh-control.js +347 -0
- package/build/angular/components/refresh-control.js.map +1 -0
- package/build/angular/components/safe-area-view.d.ts +57 -0
- package/build/angular/components/safe-area-view.js +253 -0
- package/build/angular/components/safe-area-view.js.map +1 -0
- package/build/angular/components/scroll-view/index.android.d.ts +21 -0
- package/build/angular/components/scroll-view/index.android.js +235 -0
- package/build/angular/components/scroll-view/index.android.js.map +1 -0
- package/build/angular/components/scroll-view/index.d.ts +3 -0
- package/build/angular/components/scroll-view/index.ios.d.ts +9 -0
- package/build/angular/components/scroll-view/index.ios.js +86 -0
- package/build/angular/components/scroll-view/index.ios.js.map +1 -0
- package/build/angular/components/scroll-view/index.js +6 -0
- package/build/angular/components/scroll-view/index.js.map +1 -0
- package/build/angular/components/scroll-view/projection.d.ts +32 -0
- package/build/angular/components/scroll-view/projection.js +312 -0
- package/build/angular/components/scroll-view/projection.js.map +1 -0
- package/build/angular/components/scroll-view/shared.d.ts +230 -0
- package/build/angular/components/scroll-view/shared.js +679 -0
- package/build/angular/components/scroll-view/shared.js.map +1 -0
- package/build/angular/components/scroll-view/sticky-header.d.ts +41 -0
- package/build/angular/components/scroll-view/sticky-header.js +208 -0
- package/build/angular/components/scroll-view/sticky-header.js.map +1 -0
- package/build/angular/components/section-list/index.d.ts +116 -0
- package/build/angular/components/section-list/index.js +641 -0
- package/build/angular/components/section-list/index.js.map +1 -0
- package/build/angular/components/switch/index.android.d.ts +20 -0
- package/build/angular/components/switch/index.android.js +70 -0
- package/build/angular/components/switch/index.android.js.map +1 -0
- package/build/angular/components/switch/index.d.ts +1 -0
- package/build/angular/components/switch/index.ios.d.ts +19 -0
- package/build/angular/components/switch/index.ios.js +69 -0
- package/build/angular/components/switch/index.ios.js.map +1 -0
- package/build/angular/components/switch/index.js +4 -0
- package/build/angular/components/switch/index.js.map +1 -0
- package/build/angular/components/switch/shared.d.ts +40 -0
- package/build/angular/components/switch/shared.js +127 -0
- package/build/angular/components/switch/shared.js.map +1 -0
- package/build/angular/components/text-input.d.ts +153 -0
- package/build/angular/components/text-input.js +604 -0
- package/build/angular/components/text-input.js.map +1 -0
- package/build/angular/components/touchable-native-feedback.d.ts +83 -0
- package/build/angular/components/touchable-native-feedback.js +376 -0
- package/build/angular/components/touchable-native-feedback.js.map +1 -0
- package/build/angular/components/touchable.d.ts +248 -0
- package/build/angular/components/touchable.js +1206 -0
- package/build/angular/components/touchable.js.map +1 -0
- package/build/angular/components/virtualized-list/directives.d.ts +54 -0
- package/build/angular/components/virtualized-list/directives.js +154 -0
- package/build/angular/components/virtualized-list/directives.js.map +1 -0
- package/build/angular/components/virtualized-list/index.d.ts +268 -0
- package/build/angular/components/virtualized-list/index.js +1162 -0
- package/build/angular/components/virtualized-list/index.js.map +1 -0
- package/build/angular/components/virtualized-section-list/directives.d.ts +37 -0
- package/build/angular/components/virtualized-section-list/directives.js +77 -0
- package/build/angular/components/virtualized-section-list/directives.js.map +1 -0
- package/build/angular/components/virtualized-section-list/index.d.ts +178 -0
- package/build/angular/components/virtualized-section-list/index.js +722 -0
- package/build/angular/components/virtualized-section-list/index.js.map +1 -0
- package/build/angular/components.d.ts +39 -0
- package/build/angular/components.js +38 -0
- package/build/angular/components.js.map +1 -0
- package/build/angular/create-portal.d.ts +22 -0
- package/build/angular/create-portal.js +74 -0
- package/build/angular/create-portal.js.map +1 -0
- package/build/angular/create-tunnel.d.ts +34 -0
- package/build/angular/create-tunnel.js +126 -0
- package/build/angular/create-tunnel.js.map +1 -0
- package/build/angular/descriptor-to-angular/index.d.ts +22 -0
- package/build/angular/descriptor-to-angular/index.js +142 -0
- package/build/angular/descriptor-to-angular/index.js.map +1 -0
- package/build/angular/host-instance/index.d.ts +2 -0
- package/build/angular/host-instance/index.js +37 -0
- package/build/angular/host-instance/index.js.map +1 -0
- package/build/angular/index.d.ts +21 -0
- package/build/angular/index.js +42 -0
- package/build/angular/index.js.map +1 -0
- package/build/angular/modules/animated/create-animated-component.d.ts +68 -0
- package/build/angular/modules/animated/create-animated-component.js +429 -0
- package/build/angular/modules/animated/create-animated-component.js.map +1 -0
- package/build/angular/modules/animated/index.d.ts +51 -0
- package/build/angular/modules/animated/index.js +59 -0
- package/build/angular/modules/animated/index.js.map +1 -0
- package/build/angular/modules/app-registry/index.d.ts +7 -0
- package/build/angular/modules/app-registry/index.js +23 -0
- package/build/angular/modules/app-registry/index.js.map +1 -0
- package/build/angular/modules/status-bar.d.ts +20 -0
- package/build/angular/modules/status-bar.js +59 -0
- package/build/angular/modules/status-bar.js.map +1 -0
- package/build/angular/primitives/index.d.ts +63 -0
- package/build/angular/primitives/index.js +189 -0
- package/build/angular/primitives/index.js.map +1 -0
- package/build/angular/primitives/shared.d.ts +89 -0
- package/build/angular/primitives/shared.js +172 -0
- package/build/angular/primitives/shared.js.map +1 -0
- package/build/angular/render.d.ts +11 -0
- package/build/angular/render.js +161 -0
- package/build/angular/render.js.map +1 -0
- package/build/angular/renderer.d.ts +38 -0
- package/build/angular/renderer.js +360 -0
- package/build/angular/renderer.js.map +1 -0
- package/build/angular/services/color-scheme.service.d.ts +16 -0
- package/build/angular/services/color-scheme.service.js +31 -0
- package/build/angular/services/color-scheme.service.js.map +1 -0
- package/build/angular/services/index.d.ts +2 -0
- package/build/angular/services/index.js +3 -0
- package/build/angular/services/index.js.map +1 -0
- package/build/angular/services/window-dimensions.service.d.ts +16 -0
- package/build/angular/services/window-dimensions.service.js +42 -0
- package/build/angular/services/window-dimensions.service.js.map +1 -0
- package/build/components/activity-indicator/index.android.d.ts +9 -0
- package/build/components/activity-indicator/index.android.js +64 -0
- package/build/components/activity-indicator/index.d.ts +1 -0
- package/build/components/activity-indicator/index.ios.d.ts +5 -0
- package/build/components/activity-indicator/index.ios.js +64 -0
- package/build/components/activity-indicator/index.js +3 -0
- package/build/components/activity-indicator/shared.d.ts +64 -0
- package/build/components/activity-indicator/shared.js +424 -0
- package/build/components/button.d.ts +60 -0
- package/build/components/button.js +456 -0
- package/build/components/drawer-layout-android/index.android.d.ts +29 -0
- package/build/components/drawer-layout-android/index.android.js +326 -0
- package/build/components/drawer-layout-android/index.d.ts +8 -0
- package/build/components/drawer-layout-android/index.js +145 -0
- package/build/components/drawer-layout-android/shared.d.ts +71 -0
- package/build/components/drawer-layout-android/shared.js +205 -0
- package/build/components/flat-list/index.d.ts +119 -0
- package/build/components/flat-list/index.js +692 -0
- package/build/components/image/index.android.d.ts +7 -0
- package/build/components/image/index.android.js +88 -0
- package/build/components/image/index.d.ts +1 -0
- package/build/components/image/index.ios.d.ts +7 -0
- package/build/components/image/index.ios.js +88 -0
- package/build/components/image/index.js +2 -0
- package/build/components/image/shared.d.ts +101 -0
- package/build/components/image/shared.js +407 -0
- package/build/components/image-background.d.ts +78 -0
- package/build/components/image-background.js +583 -0
- package/build/components/input-accessory-view.d.ts +56 -0
- package/build/components/input-accessory-view.js +407 -0
- package/build/components/keyboard-avoiding-view.d.ts +79 -0
- package/build/components/keyboard-avoiding-view.js +509 -0
- package/build/components/modal.d.ts +89 -0
- package/build/components/modal.js +534 -0
- package/build/components/pressable/index.d.ts +120 -0
- package/build/components/pressable/index.js +640 -0
- package/build/components/refresh-control.d.ts +83 -0
- package/build/components/refresh-control.js +514 -0
- package/build/components/safe-area-view.d.ts +54 -0
- package/build/components/safe-area-view.js +393 -0
- package/build/components/scroll-view/index.android.d.ts +16 -0
- package/build/components/scroll-view/index.android.js +228 -0
- package/build/components/scroll-view/index.d.ts +3 -0
- package/build/components/scroll-view/index.ios.d.ts +6 -0
- package/build/components/scroll-view/index.ios.js +113 -0
- package/build/components/scroll-view/index.js +5 -0
- package/build/components/scroll-view/projection.d.ts +32 -0
- package/build/components/scroll-view/projection.js +311 -0
- package/build/components/scroll-view/shared.d.ts +225 -0
- package/build/components/scroll-view/shared.js +757 -0
- package/build/components/scroll-view/sticky-header.d.ts +38 -0
- package/build/components/scroll-view/sticky-header.js +257 -0
- package/build/components/section-list/index.d.ts +113 -0
- package/build/components/section-list/index.js +768 -0
- package/build/components/switch/index.android.d.ts +17 -0
- package/build/components/switch/index.android.js +107 -0
- package/build/components/switch/index.d.ts +1 -0
- package/build/components/switch/index.ios.d.ts +16 -0
- package/build/components/switch/index.ios.js +106 -0
- package/build/components/switch/index.js +3 -0
- package/build/components/switch/shared.d.ts +37 -0
- package/build/components/switch/shared.js +176 -0
- package/build/components/text-input.d.ts +150 -0
- package/build/components/text-input.js +826 -0
- package/build/components/touchable-native-feedback.d.ts +80 -0
- package/build/components/touchable-native-feedback.js +550 -0
- package/build/components/touchable.d.ts +241 -0
- package/build/components/touchable.js +1672 -0
- package/build/components/virtualized-list/directives.d.ts +41 -0
- package/build/components/virtualized-list/directives.js +250 -0
- package/build/components/virtualized-list/index.d.ts +265 -0
- package/build/components/virtualized-list/index.js +1344 -0
- package/build/components/virtualized-section-list/directives.d.ts +28 -0
- package/build/components/virtualized-section-list/directives.js +149 -0
- package/build/components/virtualized-section-list/index.d.ts +175 -0
- package/build/components/virtualized-section-list/index.js +854 -0
- package/build/components.d.ts +39 -0
- package/build/components.js +37 -0
- package/build/create-portal.d.ts +17 -0
- package/build/create-portal.js +128 -0
- package/build/create-tunnel.d.ts +29 -0
- package/build/create-tunnel.js +181 -0
- package/build/descriptor-to-angular/index.d.ts +19 -0
- package/build/descriptor-to-angular/index.js +186 -0
- package/build/host-instance/index.d.ts +2 -0
- package/build/host-instance/index.js +36 -0
- package/build/index.d.ts +21 -0
- package/build/index.js +41 -0
- package/build/modules/animated/create-animated-component.d.ts +57 -0
- package/build/modules/animated/create-animated-component.js +490 -0
- package/build/modules/animated/index.d.ts +51 -0
- package/build/modules/animated/index.js +58 -0
- package/build/modules/app-registry/index.d.ts +7 -0
- package/build/modules/app-registry/index.js +22 -0
- package/build/modules/status-bar.d.ts +17 -0
- package/build/modules/status-bar.js +121 -0
- package/build/primitives/index.d.ts +32 -0
- package/build/primitives/index.js +386 -0
- package/build/primitives/shared.d.ts +84 -0
- package/build/primitives/shared.js +231 -0
- package/build/render.d.ts +11 -0
- package/build/render.js +160 -0
- package/build/renderer.d.ts +38 -0
- package/build/renderer.js +359 -0
- package/build/services/color-scheme.service.d.ts +13 -0
- package/build/services/color-scheme.service.js +72 -0
- package/build/services/index.d.ts +2 -0
- package/build/services/index.js +2 -0
- package/build/services/window-dimensions.service.d.ts +13 -0
- package/build/services/window-dimensions.service.js +83 -0
- package/metro-css-parser.cjs +11 -0
- package/package.json +57 -0
- package/src/__tests__/responder-change-detection.test.ts +102 -0
- package/src/__tests__/responder-nested-cd.test.ts +113 -0
- package/src/angular-gaps.test.ts +142 -0
- package/src/angular-imports.test.ts +100 -0
- package/src/components/activity-indicator/activity-indicator-class-style.test.ts +44 -0
- package/src/components/activity-indicator/activity-indicator.test.ts +131 -0
- package/src/components/activity-indicator/index.android.ts +16 -0
- package/src/components/activity-indicator/index.ios.ts +17 -0
- package/src/components/activity-indicator/index.ts +4 -0
- package/src/components/activity-indicator/shared.ts +206 -0
- package/src/components/button.ts +193 -0
- package/src/components/flat-list/column-wrapper-style-class.test.ts +116 -0
- package/src/components/flat-list/flat-list-array-style.test.ts +131 -0
- package/src/components/flat-list/flat-list-class-style.test.ts +74 -0
- package/src/components/flat-list/flat-list-scroll-containment.test.ts +107 -0
- package/src/components/flat-list/flat-list.test.ts +99 -0
- package/src/components/flat-list/index.ts +575 -0
- package/src/components/image/image-class-style.test.ts +46 -0
- package/src/components/image/index.android.ts +48 -0
- package/src/components/image/index.ios.ts +48 -0
- package/src/components/image/index.ts +3 -0
- package/src/components/image/shared.ts +478 -0
- package/src/components/image-background-class-style.test.ts +48 -0
- package/src/components/image-background-style-class.test.ts +79 -0
- package/src/components/image-background.ts +270 -0
- package/src/components/input-accessory-view.test.ts +43 -0
- package/src/components/input-accessory-view.ts +191 -0
- package/src/components/keyboard-avoiding-view.test.ts +54 -0
- package/src/components/keyboard-avoiding-view.ts +308 -0
- package/src/components/modal.test.ts +43 -0
- package/src/components/modal.ts +304 -0
- package/src/components/pressable/index.ts +371 -0
- package/src/components/pressable/pressable.test.ts +85 -0
- package/src/components/refresh-control.test.ts +41 -0
- package/src/components/refresh-control.ts +288 -0
- package/src/components/safe-area-view.test.ts +43 -0
- package/src/components/safe-area-view.ts +178 -0
- package/src/components/scroll-view/android-scroll-view-axis-projection.test.ts +123 -0
- package/src/components/scroll-view/content-container-style-class.test.ts +75 -0
- package/src/components/scroll-view/index.android.ts +190 -0
- package/src/components/scroll-view/index.ios.ts +79 -0
- package/src/components/scroll-view/index.ts +7 -0
- package/src/components/scroll-view/projection.ts +384 -0
- package/src/components/scroll-view/scroll-view-class-style.test.ts +134 -0
- package/src/components/scroll-view/scroll-view-projection.test.ts +194 -0
- package/src/components/scroll-view/shared.ts +836 -0
- package/src/components/scroll-view/sticky-header.ts +230 -0
- package/src/components/section-list/index.ts +445 -0
- package/src/components/switch/android-switch-class.test.ts +42 -0
- package/src/components/switch/index.android.ts +61 -0
- package/src/components/switch/index.ios.ts +60 -0
- package/src/components/switch/index.ts +4 -0
- package/src/components/switch/shared.ts +197 -0
- package/src/components/switch/switch.test.ts +92 -0
- package/src/components/text-input-class-style.test.ts +54 -0
- package/src/components/text-input.ts +536 -0
- package/src/components/touchable-native-feedback.test.ts +49 -0
- package/src/components/touchable-native-feedback.ts +260 -0
- package/src/components/touchable.test.ts +102 -0
- package/src/components/touchable.ts +643 -0
- package/src/components/virtualized-list/directives.ts +169 -0
- package/src/components/virtualized-list/index.ts +1204 -0
- package/src/components/virtualized-list/virtualized-list-class-style.test.ts +76 -0
- package/src/components/virtualized-section-list/directives.ts +91 -0
- package/src/components/virtualized-section-list/index.ts +598 -0
- package/src/components/virtualized-section-list/virtualized-section-list-class-style.test.ts +60 -0
- package/src/components.ts +149 -0
- package/src/create-portal.test.ts +90 -0
- package/src/create-portal.ts +74 -0
- package/src/create-tunnel.test.ts +120 -0
- package/src/create-tunnel.ts +136 -0
- package/src/descriptor-to-angular/descriptor-outlet.test.ts +94 -0
- package/src/descriptor-to-angular/index.ts +190 -0
- package/src/host-instance/host-instance.test.ts +49 -0
- package/src/host-instance/index.ts +36 -0
- package/src/index.ts +257 -0
- package/src/modules/animated/animated-scroll-view.test.ts +85 -0
- package/src/modules/animated/create-animated-component.ts +435 -0
- package/src/modules/animated/index.ts +105 -0
- package/src/modules/app-registry/app-registry.test.ts +106 -0
- package/src/modules/app-registry/index.ts +60 -0
- package/src/modules/status-bar.test.ts +50 -0
- package/src/modules/status-bar.ts +57 -0
- package/src/primitives/index.ts +119 -0
- package/src/primitives/shared.ts +191 -0
- package/src/render.test.ts +147 -0
- package/src/render.ts +224 -0
- package/src/renderer.test.ts +179 -0
- package/src/renderer.ts +407 -0
- package/src/services/color-scheme.service.ts +27 -0
- package/src/services/index.ts +2 -0
- package/src/services/services.test.ts +163 -0
- package/src/services/window-dimensions.service.ts +41 -0
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
// The Touchable* family for Angular, all built on Pressable (the Angular twin of the React/Vue
|
|
2
|
+
// adapter). The press-timing constants and the deactivation-floor math are shared with every
|
|
3
|
+
// adapter (@symbiote-native/components/state/touchable); here Angular owns only the Animated wiring + the
|
|
4
|
+
// press scheduling state:
|
|
5
|
+
// TouchableOpacity: animate an Animated.Value opacity toward activeOpacity on press-in and back
|
|
6
|
+
// to 1 on press-out, driven from Pressable's onPressIn/onPressOut. The opacity Value is held by
|
|
7
|
+
// IDENTITY as a plain field (an engine object, never an @Input / reactive wrap) and the
|
|
8
|
+
// <symbiote-animated-view> leaf commits it every frame.
|
|
9
|
+
// TouchableHighlight: paint underlayColor + lower child opacity while pressed, via Pressable's
|
|
10
|
+
// style-as-function (Pressable drives the pressed flag through its own responder lifecycle).
|
|
11
|
+
// TouchableWithoutFeedback: no visual change, just the press wiring forwarded through Pressable.
|
|
12
|
+
//
|
|
13
|
+
// Every Touchable's own press/hover/accessibility events are now real @Output() EventEmitters too,
|
|
14
|
+
// matching Pressable (which they wrap) — `(press)="handler($event)"`, never `[onPress]="handler"`.
|
|
15
|
+
// Non-event config (delayLongPress, hitSlop, ...) still rides down as plain @Input() bindings.
|
|
16
|
+
// Accessibility EVENTS forward straight through to Pressable's own outputs
|
|
17
|
+
// (`(accessibilityAction)="accessibilityAction.emit($event)"`); accessibility STATE folds the web
|
|
18
|
+
// aria-*/role aliases and merges `disabled` into the a11y state on Pressable's own host — no re-fold
|
|
19
|
+
// here (the a11y host is Pressable's view, mirroring React's `...rest` -> Pressable). No JS-side
|
|
20
|
+
// platform branch, so this stays a flat single file (see the
|
|
21
|
+
// symbiote-file-layout skill), mirroring React/Vue. Each Touchable forwards the Angular Pressable
|
|
22
|
+
// surface verbatim; parity is against that surface, exactly as React's Touchable parity is against
|
|
23
|
+
// the React Pressable surface.
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
CUSTOM_ELEMENTS_SCHEMA,
|
|
27
|
+
ChangeDetectionStrategy,
|
|
28
|
+
Component,
|
|
29
|
+
ElementRef,
|
|
30
|
+
EventEmitter,
|
|
31
|
+
inject,
|
|
32
|
+
Input,
|
|
33
|
+
Output,
|
|
34
|
+
} from '@angular/core';
|
|
35
|
+
import {
|
|
36
|
+
computePressOutWait,
|
|
37
|
+
DEFAULT_ACTIVE_OPACITY,
|
|
38
|
+
DEFAULT_HIGHLIGHT_CHILD_OPACITY,
|
|
39
|
+
DEFAULT_MIN_PRESS_DURATION_MS,
|
|
40
|
+
DEFAULT_UNDERLAY_COLOR,
|
|
41
|
+
OPACITY_ACTIVE_DURATION_MS,
|
|
42
|
+
OPACITY_INACTIVE_DURATION_MS,
|
|
43
|
+
RESTING_OPACITY,
|
|
44
|
+
type IAccessibilityProps,
|
|
45
|
+
type IAccessibilityStateValue,
|
|
46
|
+
type IAriaProps,
|
|
47
|
+
type IPressableAndroidRippleConfig,
|
|
48
|
+
type IPressState,
|
|
49
|
+
type IPressTimingProps,
|
|
50
|
+
type IRectOffset,
|
|
51
|
+
} from '@symbiote-native/components';
|
|
52
|
+
import {
|
|
53
|
+
dlog,
|
|
54
|
+
type ISymbioteEvent,
|
|
55
|
+
type IStyleProp,
|
|
56
|
+
type IViewStyle,
|
|
57
|
+
} from '@symbiote-native/engine';
|
|
58
|
+
import { anchorHostStyle, anchorStyleProp } from '../primitives';
|
|
59
|
+
import { Pressable, type IAngularPressableInputs } from './pressable';
|
|
60
|
+
import { Animated, AnimatedView } from '../modules/animated';
|
|
61
|
+
|
|
62
|
+
// The shared field base for all three: the Pressable INPUT surface (minus style, which each
|
|
63
|
+
// Touchable routes differently, and minus the press/hover events, which each Touchable declares as
|
|
64
|
+
// its OWN @Output()s below) + RN's press-timing config + the public style. Mirrors React/Vue's
|
|
65
|
+
// ITouchableBaseProps. Declared per-adapter over the Angular Pressable surface per
|
|
66
|
+
// <prop_types_split_agnostic_vs_per_adapter> (children ride <ng-content>, so they are not a field).
|
|
67
|
+
type IAngularTouchableBaseProps = Omit<IAngularPressableInputs, 'style'> &
|
|
68
|
+
IPressTimingProps & {
|
|
69
|
+
style?: IStyleProp<IViewStyle>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type IAngularTouchableOpacityProps = IAngularTouchableBaseProps & {
|
|
73
|
+
activeOpacity?: number;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export type IAngularTouchableHighlightProps = IAngularTouchableBaseProps & {
|
|
77
|
+
activeOpacity?: number;
|
|
78
|
+
underlayColor?: string;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type IAngularTouchableWithoutFeedbackProps = IAngularTouchableBaseProps;
|
|
82
|
+
|
|
83
|
+
@Component({
|
|
84
|
+
selector: 'TouchableOpacity',
|
|
85
|
+
standalone: true,
|
|
86
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
87
|
+
imports: [Pressable, AnimatedView],
|
|
88
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
89
|
+
template: `
|
|
90
|
+
<Pressable
|
|
91
|
+
(press)="press.emit($event)"
|
|
92
|
+
(pressIn)="handlePressIn($event)"
|
|
93
|
+
(pressOut)="handlePressOut($event)"
|
|
94
|
+
(pressMove)="pressMove.emit($event)"
|
|
95
|
+
(longPress)="longPress.emit($event)"
|
|
96
|
+
(hoverIn)="hoverIn.emit($event)"
|
|
97
|
+
(hoverOut)="hoverOut.emit($event)"
|
|
98
|
+
[delayLongPress]="delayLongPress"
|
|
99
|
+
[delayHoverIn]="delayHoverIn"
|
|
100
|
+
[delayHoverOut]="delayHoverOut"
|
|
101
|
+
[disabled]="disabled"
|
|
102
|
+
[cancelable]="cancelable"
|
|
103
|
+
[hitSlop]="hitSlop"
|
|
104
|
+
[pressRetentionOffset]="pressRetentionOffset"
|
|
105
|
+
[unstable_pressDelay]="unstable_pressDelay"
|
|
106
|
+
[android_ripple]="android_ripple"
|
|
107
|
+
[android_disableSound]="android_disableSound"
|
|
108
|
+
[testID]="testID"
|
|
109
|
+
[nativeID]="nativeID"
|
|
110
|
+
[hasTVPreferredFocus]="hasTVPreferredFocus"
|
|
111
|
+
[nextFocusDown]="nextFocusDown"
|
|
112
|
+
[nextFocusForward]="nextFocusForward"
|
|
113
|
+
[nextFocusLeft]="nextFocusLeft"
|
|
114
|
+
[nextFocusRight]="nextFocusRight"
|
|
115
|
+
[nextFocusUp]="nextFocusUp"
|
|
116
|
+
[accessible]="accessible"
|
|
117
|
+
[accessibilityLabel]="accessibilityLabel"
|
|
118
|
+
[accessibilityHint]="accessibilityHint"
|
|
119
|
+
[accessibilityRole]="accessibilityRole"
|
|
120
|
+
[accessibilityState]="accessibilityState"
|
|
121
|
+
[accessibilityValue]="accessibilityValue"
|
|
122
|
+
[accessibilityActions]="accessibilityActions"
|
|
123
|
+
[accessibilityLabelledBy]="accessibilityLabelledBy"
|
|
124
|
+
[importantForAccessibility]="importantForAccessibility"
|
|
125
|
+
[accessibilityLiveRegion]="accessibilityLiveRegion"
|
|
126
|
+
[screenReaderFocusable]="screenReaderFocusable"
|
|
127
|
+
[accessibilityViewIsModal]="accessibilityViewIsModal"
|
|
128
|
+
[accessibilityElementsHidden]="accessibilityElementsHidden"
|
|
129
|
+
[accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
|
|
130
|
+
[accessibilityLanguage]="accessibilityLanguage"
|
|
131
|
+
[accessibilityRespondsToUserInteraction]="accessibilityRespondsToUserInteraction"
|
|
132
|
+
[accessibilityShowsLargeContentViewer]="accessibilityShowsLargeContentViewer"
|
|
133
|
+
[accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
|
|
134
|
+
(accessibilityAction)="accessibilityAction.emit($event)"
|
|
135
|
+
(accessibilityTap)="accessibilityTap.emit($event)"
|
|
136
|
+
(magicTap)="magicTap.emit($event)"
|
|
137
|
+
(accessibilityEscape)="accessibilityEscape.emit($event)"
|
|
138
|
+
[ariaLabel]="ariaLabel"
|
|
139
|
+
[ariaBusy]="ariaBusy"
|
|
140
|
+
[ariaChecked]="ariaChecked"
|
|
141
|
+
[ariaDisabled]="ariaDisabled"
|
|
142
|
+
[ariaExpanded]="ariaExpanded"
|
|
143
|
+
[ariaHidden]="ariaHidden"
|
|
144
|
+
[ariaLabelledBy]="ariaLabelledBy"
|
|
145
|
+
[ariaLive]="ariaLive"
|
|
146
|
+
[ariaSelected]="ariaSelected"
|
|
147
|
+
[ariaModal]="ariaModal"
|
|
148
|
+
[ariaValueMax]="ariaValueMax"
|
|
149
|
+
[ariaValueMin]="ariaValueMin"
|
|
150
|
+
[ariaValueNow]="ariaValueNow"
|
|
151
|
+
[ariaValueText]="ariaValueText"
|
|
152
|
+
[id]="id"
|
|
153
|
+
[role]="role"
|
|
154
|
+
>
|
|
155
|
+
<symbiote-animated-view [style]="animatedStyle">
|
|
156
|
+
<ng-content></ng-content>
|
|
157
|
+
</symbiote-animated-view>
|
|
158
|
+
</Pressable>
|
|
159
|
+
`,
|
|
160
|
+
})
|
|
161
|
+
export class TouchableOpacity implements IAngularTouchableOpacityProps {
|
|
162
|
+
@Output() readonly press = new EventEmitter<ISymbioteEvent>();
|
|
163
|
+
@Output() readonly pressIn = new EventEmitter<ISymbioteEvent>();
|
|
164
|
+
@Output() readonly pressOut = new EventEmitter<ISymbioteEvent>();
|
|
165
|
+
@Output() readonly pressMove = new EventEmitter<ISymbioteEvent>();
|
|
166
|
+
@Output() readonly longPress = new EventEmitter<ISymbioteEvent>();
|
|
167
|
+
@Output() readonly hoverIn = new EventEmitter<ISymbioteEvent>();
|
|
168
|
+
@Output() readonly hoverOut = new EventEmitter<ISymbioteEvent>();
|
|
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() activeOpacity?: number;
|
|
174
|
+
@Input() delayPressIn?: number;
|
|
175
|
+
@Input() delayPressOut?: number;
|
|
176
|
+
@Input() minPressDuration?: number;
|
|
177
|
+
@Input() style?: IStyleProp<IViewStyle>;
|
|
178
|
+
@Input() delayLongPress?: number;
|
|
179
|
+
@Input() delayHoverIn?: number;
|
|
180
|
+
@Input() delayHoverOut?: number;
|
|
181
|
+
@Input() disabled?: boolean;
|
|
182
|
+
@Input() cancelable?: boolean;
|
|
183
|
+
@Input() hitSlop?: IRectOffset;
|
|
184
|
+
@Input() pressRetentionOffset?: IRectOffset;
|
|
185
|
+
@Input() unstable_pressDelay?: number;
|
|
186
|
+
@Input() android_ripple?: IPressableAndroidRippleConfig;
|
|
187
|
+
@Input() android_disableSound?: boolean;
|
|
188
|
+
@Input() testID?: string;
|
|
189
|
+
@Input() nativeID?: string;
|
|
190
|
+
@Input() hasTVPreferredFocus?: boolean;
|
|
191
|
+
@Input() nextFocusDown?: number;
|
|
192
|
+
@Input() nextFocusForward?: number;
|
|
193
|
+
@Input() nextFocusLeft?: number;
|
|
194
|
+
@Input() nextFocusRight?: number;
|
|
195
|
+
@Input() nextFocusUp?: number;
|
|
196
|
+
@Input() accessible?: boolean;
|
|
197
|
+
@Input() accessibilityLabel?: string;
|
|
198
|
+
@Input() accessibilityHint?: string;
|
|
199
|
+
@Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
|
|
200
|
+
@Input() accessibilityState?: IAccessibilityStateValue;
|
|
201
|
+
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
202
|
+
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
203
|
+
@Input() accessibilityLabelledBy?: string | string[];
|
|
204
|
+
@Input() importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
205
|
+
@Input() accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
206
|
+
@Input() screenReaderFocusable?: boolean;
|
|
207
|
+
@Input() accessibilityViewIsModal?: boolean;
|
|
208
|
+
@Input() accessibilityElementsHidden?: boolean;
|
|
209
|
+
@Input() accessibilityIgnoresInvertColors?: boolean;
|
|
210
|
+
@Input() accessibilityLanguage?: string;
|
|
211
|
+
@Input() accessibilityRespondsToUserInteraction?: boolean;
|
|
212
|
+
@Input() accessibilityShowsLargeContentViewer?: boolean;
|
|
213
|
+
@Input() accessibilityLargeContentTitle?: string;
|
|
214
|
+
@Input() ariaLabel?: string;
|
|
215
|
+
@Input() ariaBusy?: boolean;
|
|
216
|
+
@Input() ariaChecked?: boolean | 'mixed';
|
|
217
|
+
@Input() ariaDisabled?: boolean;
|
|
218
|
+
@Input() ariaExpanded?: boolean;
|
|
219
|
+
@Input() ariaHidden?: boolean;
|
|
220
|
+
@Input() ariaLabelledBy?: string;
|
|
221
|
+
@Input() ariaLive?: IAriaProps['aria-live'];
|
|
222
|
+
@Input() ariaSelected?: boolean;
|
|
223
|
+
@Input() ariaModal?: boolean;
|
|
224
|
+
@Input() ariaValueMax?: number;
|
|
225
|
+
@Input() ariaValueMin?: number;
|
|
226
|
+
@Input() ariaValueNow?: number;
|
|
227
|
+
@Input() ariaValueText?: string;
|
|
228
|
+
@Input() id?: string;
|
|
229
|
+
@Input() role?: IAriaProps['role'];
|
|
230
|
+
|
|
231
|
+
// One Animated.Value per mount, resting at full opacity. Held by IDENTITY as a plain field (an
|
|
232
|
+
// engine object, never an @Input / reactive wrap); the <symbiote-animated-view> leaf rasterizes
|
|
233
|
+
// it for the first paint and drives it through setNativeProps every frame.
|
|
234
|
+
private readonly opacity = new Animated.Value(RESTING_OPACITY);
|
|
235
|
+
// The pending delayPressIn timer, so a release before it fires can flush it.
|
|
236
|
+
private pressInTimer: ReturnType<typeof setTimeout> | undefined;
|
|
237
|
+
// When the active visual actually started, to floor onPressOut by minPressDuration.
|
|
238
|
+
private activatedAt: number | undefined;
|
|
239
|
+
// This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
|
|
240
|
+
// onto (see anchorHostStyle's doc comment) — NOT the <symbiote-animated-view> leaf one level down.
|
|
241
|
+
private readonly elementRef = inject(ElementRef);
|
|
242
|
+
|
|
243
|
+
// The (possibly animated) style the leaf reduces: the anchor's class-derived style first, then
|
|
244
|
+
// the user's explicit style, then the live opacity layered on top (last wins via the style array
|
|
245
|
+
// the commit layer flattens). `unknown` because the array mixes a plain style with an
|
|
246
|
+
// AnimatedNode, exactly the bag AnimatedView's `style` input accepts.
|
|
247
|
+
get animatedStyle(): unknown {
|
|
248
|
+
return [anchorHostStyle(this.elementRef), this.style, { opacity: this.opacity }];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private setOpacityTo(toValue: number, duration: number): void {
|
|
252
|
+
Animated.timing(this.opacity, {
|
|
253
|
+
toValue,
|
|
254
|
+
duration,
|
|
255
|
+
easing: Animated.Easing.inOut(Animated.Easing.quad),
|
|
256
|
+
useNativeDriver: false,
|
|
257
|
+
}).start();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private clearPressInTimer(): void {
|
|
261
|
+
if (this.pressInTimer !== undefined) {
|
|
262
|
+
clearTimeout(this.pressInTimer);
|
|
263
|
+
this.pressInTimer = undefined;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private activate(event: ISymbioteEvent): void {
|
|
268
|
+
this.activatedAt = Date.now();
|
|
269
|
+
this.setOpacityTo(this.activeOpacity ?? DEFAULT_ACTIVE_OPACITY, OPACITY_ACTIVE_DURATION_MS);
|
|
270
|
+
this.pressIn.emit(event);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private deactivate(event: ISymbioteEvent): void {
|
|
274
|
+
this.activatedAt = undefined;
|
|
275
|
+
this.setOpacityTo(RESTING_OPACITY, OPACITY_INACTIVE_DURATION_MS);
|
|
276
|
+
this.pressOut.emit(event);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Arrow fields (stable identity for OnPush, `this` intact when Pressable's `(pressIn)` invokes
|
|
280
|
+
// them). RN's _createPressabilityConfig forwards delayPressIn — defer the active visual and
|
|
281
|
+
// pressIn behind the delay (a release before it elapses flushes it synchronously).
|
|
282
|
+
handlePressIn = (event: ISymbioteEvent): void => {
|
|
283
|
+
const delayPressIn = this.delayPressIn ?? 0;
|
|
284
|
+
if (delayPressIn > 0) {
|
|
285
|
+
dlog(`TouchableOpacity pressIn deferred ${delayPressIn}ms`);
|
|
286
|
+
this.pressInTimer = setTimeout(() => {
|
|
287
|
+
this.pressInTimer = undefined;
|
|
288
|
+
this.activate(event);
|
|
289
|
+
}, delayPressIn);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
this.activate(event);
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// delayPressOut + minPressDuration (RN _deactivate): the press-out waits at least minPressDuration
|
|
296
|
+
// past activation (so a fast tap holds the active visual) and at least delayPressOut, whichever is
|
|
297
|
+
// longer.
|
|
298
|
+
handlePressOut = (event: ISymbioteEvent): void => {
|
|
299
|
+
if (this.pressInTimer !== undefined) {
|
|
300
|
+
this.clearPressInTimer();
|
|
301
|
+
this.activate(event);
|
|
302
|
+
}
|
|
303
|
+
const heldFor = this.activatedAt === undefined ? 0 : Date.now() - this.activatedAt;
|
|
304
|
+
const wait = computePressOutWait(
|
|
305
|
+
heldFor,
|
|
306
|
+
this.minPressDuration ?? DEFAULT_MIN_PRESS_DURATION_MS,
|
|
307
|
+
this.delayPressOut ?? 0,
|
|
308
|
+
);
|
|
309
|
+
if (wait > 0) {
|
|
310
|
+
dlog(`TouchableOpacity pressOut deferred ${wait}ms`);
|
|
311
|
+
setTimeout(() => this.deactivate(event), wait);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
this.deactivate(event);
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@Component({
|
|
319
|
+
selector: 'TouchableHighlight',
|
|
320
|
+
standalone: true,
|
|
321
|
+
imports: [Pressable],
|
|
322
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
323
|
+
template: `
|
|
324
|
+
<Pressable
|
|
325
|
+
[style]="pressedStyle"
|
|
326
|
+
(press)="press.emit($event)"
|
|
327
|
+
(pressIn)="pressIn.emit($event)"
|
|
328
|
+
(pressOut)="pressOut.emit($event)"
|
|
329
|
+
(pressMove)="pressMove.emit($event)"
|
|
330
|
+
(longPress)="longPress.emit($event)"
|
|
331
|
+
(hoverIn)="hoverIn.emit($event)"
|
|
332
|
+
(hoverOut)="hoverOut.emit($event)"
|
|
333
|
+
[delayLongPress]="delayLongPress"
|
|
334
|
+
[delayHoverIn]="delayHoverIn"
|
|
335
|
+
[delayHoverOut]="delayHoverOut"
|
|
336
|
+
[disabled]="disabled"
|
|
337
|
+
[cancelable]="cancelable"
|
|
338
|
+
[hitSlop]="hitSlop"
|
|
339
|
+
[pressRetentionOffset]="pressRetentionOffset"
|
|
340
|
+
[unstable_pressDelay]="unstable_pressDelay"
|
|
341
|
+
[android_ripple]="android_ripple"
|
|
342
|
+
[android_disableSound]="android_disableSound"
|
|
343
|
+
[testID]="testID"
|
|
344
|
+
[nativeID]="nativeID"
|
|
345
|
+
[hasTVPreferredFocus]="hasTVPreferredFocus"
|
|
346
|
+
[nextFocusDown]="nextFocusDown"
|
|
347
|
+
[nextFocusForward]="nextFocusForward"
|
|
348
|
+
[nextFocusLeft]="nextFocusLeft"
|
|
349
|
+
[nextFocusRight]="nextFocusRight"
|
|
350
|
+
[nextFocusUp]="nextFocusUp"
|
|
351
|
+
[accessible]="accessible"
|
|
352
|
+
[accessibilityLabel]="accessibilityLabel"
|
|
353
|
+
[accessibilityHint]="accessibilityHint"
|
|
354
|
+
[accessibilityRole]="accessibilityRole"
|
|
355
|
+
[accessibilityState]="accessibilityState"
|
|
356
|
+
[accessibilityValue]="accessibilityValue"
|
|
357
|
+
[accessibilityActions]="accessibilityActions"
|
|
358
|
+
[accessibilityLabelledBy]="accessibilityLabelledBy"
|
|
359
|
+
[importantForAccessibility]="importantForAccessibility"
|
|
360
|
+
[accessibilityLiveRegion]="accessibilityLiveRegion"
|
|
361
|
+
[screenReaderFocusable]="screenReaderFocusable"
|
|
362
|
+
[accessibilityViewIsModal]="accessibilityViewIsModal"
|
|
363
|
+
[accessibilityElementsHidden]="accessibilityElementsHidden"
|
|
364
|
+
[accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
|
|
365
|
+
[accessibilityLanguage]="accessibilityLanguage"
|
|
366
|
+
[accessibilityRespondsToUserInteraction]="accessibilityRespondsToUserInteraction"
|
|
367
|
+
[accessibilityShowsLargeContentViewer]="accessibilityShowsLargeContentViewer"
|
|
368
|
+
[accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
|
|
369
|
+
(accessibilityAction)="accessibilityAction.emit($event)"
|
|
370
|
+
(accessibilityTap)="accessibilityTap.emit($event)"
|
|
371
|
+
(magicTap)="magicTap.emit($event)"
|
|
372
|
+
(accessibilityEscape)="accessibilityEscape.emit($event)"
|
|
373
|
+
[ariaLabel]="ariaLabel"
|
|
374
|
+
[ariaBusy]="ariaBusy"
|
|
375
|
+
[ariaChecked]="ariaChecked"
|
|
376
|
+
[ariaDisabled]="ariaDisabled"
|
|
377
|
+
[ariaExpanded]="ariaExpanded"
|
|
378
|
+
[ariaHidden]="ariaHidden"
|
|
379
|
+
[ariaLabelledBy]="ariaLabelledBy"
|
|
380
|
+
[ariaLive]="ariaLive"
|
|
381
|
+
[ariaSelected]="ariaSelected"
|
|
382
|
+
[ariaModal]="ariaModal"
|
|
383
|
+
[ariaValueMax]="ariaValueMax"
|
|
384
|
+
[ariaValueMin]="ariaValueMin"
|
|
385
|
+
[ariaValueNow]="ariaValueNow"
|
|
386
|
+
[ariaValueText]="ariaValueText"
|
|
387
|
+
[id]="id"
|
|
388
|
+
[role]="role"
|
|
389
|
+
>
|
|
390
|
+
<ng-content></ng-content>
|
|
391
|
+
</Pressable>
|
|
392
|
+
`,
|
|
393
|
+
})
|
|
394
|
+
export class TouchableHighlight implements IAngularTouchableHighlightProps {
|
|
395
|
+
@Output() readonly press = new EventEmitter<ISymbioteEvent>();
|
|
396
|
+
@Output() readonly pressIn = new EventEmitter<ISymbioteEvent>();
|
|
397
|
+
@Output() readonly pressOut = new EventEmitter<ISymbioteEvent>();
|
|
398
|
+
@Output() readonly pressMove = new EventEmitter<ISymbioteEvent>();
|
|
399
|
+
@Output() readonly longPress = new EventEmitter<ISymbioteEvent>();
|
|
400
|
+
@Output() readonly hoverIn = new EventEmitter<ISymbioteEvent>();
|
|
401
|
+
@Output() readonly hoverOut = new EventEmitter<ISymbioteEvent>();
|
|
402
|
+
@Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
|
|
403
|
+
@Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
|
|
404
|
+
@Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
|
|
405
|
+
@Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
|
|
406
|
+
@Input() activeOpacity?: number;
|
|
407
|
+
@Input() underlayColor?: string;
|
|
408
|
+
@Input() delayPressIn?: number;
|
|
409
|
+
@Input() delayPressOut?: number;
|
|
410
|
+
@Input() minPressDuration?: number;
|
|
411
|
+
@Input() style?: IStyleProp<IViewStyle>;
|
|
412
|
+
@Input() delayLongPress?: number;
|
|
413
|
+
@Input() delayHoverIn?: number;
|
|
414
|
+
@Input() delayHoverOut?: number;
|
|
415
|
+
@Input() disabled?: boolean;
|
|
416
|
+
@Input() cancelable?: boolean;
|
|
417
|
+
@Input() hitSlop?: IRectOffset;
|
|
418
|
+
@Input() pressRetentionOffset?: IRectOffset;
|
|
419
|
+
@Input() unstable_pressDelay?: number;
|
|
420
|
+
@Input() android_ripple?: IPressableAndroidRippleConfig;
|
|
421
|
+
@Input() android_disableSound?: boolean;
|
|
422
|
+
@Input() testID?: string;
|
|
423
|
+
@Input() nativeID?: string;
|
|
424
|
+
@Input() hasTVPreferredFocus?: boolean;
|
|
425
|
+
@Input() nextFocusDown?: number;
|
|
426
|
+
@Input() nextFocusForward?: number;
|
|
427
|
+
@Input() nextFocusLeft?: number;
|
|
428
|
+
@Input() nextFocusRight?: number;
|
|
429
|
+
@Input() nextFocusUp?: number;
|
|
430
|
+
@Input() accessible?: boolean;
|
|
431
|
+
@Input() accessibilityLabel?: string;
|
|
432
|
+
@Input() accessibilityHint?: string;
|
|
433
|
+
@Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
|
|
434
|
+
@Input() accessibilityState?: IAccessibilityStateValue;
|
|
435
|
+
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
436
|
+
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
437
|
+
@Input() accessibilityLabelledBy?: string | string[];
|
|
438
|
+
@Input() importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
439
|
+
@Input() accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
440
|
+
@Input() screenReaderFocusable?: boolean;
|
|
441
|
+
@Input() accessibilityViewIsModal?: boolean;
|
|
442
|
+
@Input() accessibilityElementsHidden?: boolean;
|
|
443
|
+
@Input() accessibilityIgnoresInvertColors?: boolean;
|
|
444
|
+
@Input() accessibilityLanguage?: string;
|
|
445
|
+
@Input() accessibilityRespondsToUserInteraction?: boolean;
|
|
446
|
+
@Input() accessibilityShowsLargeContentViewer?: boolean;
|
|
447
|
+
@Input() accessibilityLargeContentTitle?: string;
|
|
448
|
+
@Input() ariaLabel?: string;
|
|
449
|
+
@Input() ariaBusy?: boolean;
|
|
450
|
+
@Input() ariaChecked?: boolean | 'mixed';
|
|
451
|
+
@Input() ariaDisabled?: boolean;
|
|
452
|
+
@Input() ariaExpanded?: boolean;
|
|
453
|
+
@Input() ariaHidden?: boolean;
|
|
454
|
+
@Input() ariaLabelledBy?: string;
|
|
455
|
+
@Input() ariaLive?: IAriaProps['aria-live'];
|
|
456
|
+
@Input() ariaSelected?: boolean;
|
|
457
|
+
@Input() ariaModal?: boolean;
|
|
458
|
+
@Input() ariaValueMax?: number;
|
|
459
|
+
@Input() ariaValueMin?: number;
|
|
460
|
+
@Input() ariaValueNow?: number;
|
|
461
|
+
@Input() ariaValueText?: string;
|
|
462
|
+
@Input() id?: string;
|
|
463
|
+
@Input() role?: IAriaProps['role'];
|
|
464
|
+
|
|
465
|
+
// This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
|
|
466
|
+
// onto (see anchorHostStyle's doc comment) — NOT the Pressable one level down.
|
|
467
|
+
private readonly elementRef = inject(ElementRef);
|
|
468
|
+
|
|
469
|
+
// Pressable accepts a style-as-function and calls it with the live pressed state. Arrow field so
|
|
470
|
+
// `this` stays bound when Pressable invokes it; it reads the inputs LIVE at call time. The
|
|
471
|
+
// anchor's class-derived style goes first, then the user's explicit style, so an explicit
|
|
472
|
+
// [style] still beats the ambient class. When pressed, paint the underlay color + lower the
|
|
473
|
+
// child opacity (RN drives this with setState, not Animated, so we mirror that faithfully
|
|
474
|
+
// through Pressable's pressed flag, no tween) — the overlay always goes last so it wins.
|
|
475
|
+
pressedStyle = (state: IPressState): IStyleProp<IViewStyle> => {
|
|
476
|
+
const anchorStyle = anchorStyleProp<IViewStyle>(this.elementRef);
|
|
477
|
+
if (!state.pressed) return [anchorStyle, this.style];
|
|
478
|
+
const overlay: IViewStyle = {
|
|
479
|
+
backgroundColor: this.underlayColor ?? DEFAULT_UNDERLAY_COLOR,
|
|
480
|
+
opacity: this.activeOpacity ?? DEFAULT_HIGHLIGHT_CHILD_OPACITY,
|
|
481
|
+
};
|
|
482
|
+
return [anchorStyle, this.style, overlay];
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
@Component({
|
|
487
|
+
selector: 'TouchableWithoutFeedback',
|
|
488
|
+
standalone: true,
|
|
489
|
+
imports: [Pressable],
|
|
490
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
491
|
+
template: `
|
|
492
|
+
<Pressable
|
|
493
|
+
[style]="mergedStyle"
|
|
494
|
+
(press)="press.emit($event)"
|
|
495
|
+
(pressIn)="pressIn.emit($event)"
|
|
496
|
+
(pressOut)="pressOut.emit($event)"
|
|
497
|
+
(pressMove)="pressMove.emit($event)"
|
|
498
|
+
(longPress)="longPress.emit($event)"
|
|
499
|
+
(hoverIn)="hoverIn.emit($event)"
|
|
500
|
+
(hoverOut)="hoverOut.emit($event)"
|
|
501
|
+
[delayLongPress]="delayLongPress"
|
|
502
|
+
[delayHoverIn]="delayHoverIn"
|
|
503
|
+
[delayHoverOut]="delayHoverOut"
|
|
504
|
+
[disabled]="disabled"
|
|
505
|
+
[cancelable]="cancelable"
|
|
506
|
+
[hitSlop]="hitSlop"
|
|
507
|
+
[pressRetentionOffset]="pressRetentionOffset"
|
|
508
|
+
[unstable_pressDelay]="unstable_pressDelay"
|
|
509
|
+
[android_ripple]="android_ripple"
|
|
510
|
+
[android_disableSound]="android_disableSound"
|
|
511
|
+
[testID]="testID"
|
|
512
|
+
[nativeID]="nativeID"
|
|
513
|
+
[hasTVPreferredFocus]="hasTVPreferredFocus"
|
|
514
|
+
[nextFocusDown]="nextFocusDown"
|
|
515
|
+
[nextFocusForward]="nextFocusForward"
|
|
516
|
+
[nextFocusLeft]="nextFocusLeft"
|
|
517
|
+
[nextFocusRight]="nextFocusRight"
|
|
518
|
+
[nextFocusUp]="nextFocusUp"
|
|
519
|
+
[accessible]="accessible"
|
|
520
|
+
[accessibilityLabel]="accessibilityLabel"
|
|
521
|
+
[accessibilityHint]="accessibilityHint"
|
|
522
|
+
[accessibilityRole]="accessibilityRole"
|
|
523
|
+
[accessibilityState]="accessibilityState"
|
|
524
|
+
[accessibilityValue]="accessibilityValue"
|
|
525
|
+
[accessibilityActions]="accessibilityActions"
|
|
526
|
+
[accessibilityLabelledBy]="accessibilityLabelledBy"
|
|
527
|
+
[importantForAccessibility]="importantForAccessibility"
|
|
528
|
+
[accessibilityLiveRegion]="accessibilityLiveRegion"
|
|
529
|
+
[screenReaderFocusable]="screenReaderFocusable"
|
|
530
|
+
[accessibilityViewIsModal]="accessibilityViewIsModal"
|
|
531
|
+
[accessibilityElementsHidden]="accessibilityElementsHidden"
|
|
532
|
+
[accessibilityIgnoresInvertColors]="accessibilityIgnoresInvertColors"
|
|
533
|
+
[accessibilityLanguage]="accessibilityLanguage"
|
|
534
|
+
[accessibilityRespondsToUserInteraction]="accessibilityRespondsToUserInteraction"
|
|
535
|
+
[accessibilityShowsLargeContentViewer]="accessibilityShowsLargeContentViewer"
|
|
536
|
+
[accessibilityLargeContentTitle]="accessibilityLargeContentTitle"
|
|
537
|
+
(accessibilityAction)="accessibilityAction.emit($event)"
|
|
538
|
+
(accessibilityTap)="accessibilityTap.emit($event)"
|
|
539
|
+
(magicTap)="magicTap.emit($event)"
|
|
540
|
+
(accessibilityEscape)="accessibilityEscape.emit($event)"
|
|
541
|
+
[ariaLabel]="ariaLabel"
|
|
542
|
+
[ariaBusy]="ariaBusy"
|
|
543
|
+
[ariaChecked]="ariaChecked"
|
|
544
|
+
[ariaDisabled]="ariaDisabled"
|
|
545
|
+
[ariaExpanded]="ariaExpanded"
|
|
546
|
+
[ariaHidden]="ariaHidden"
|
|
547
|
+
[ariaLabelledBy]="ariaLabelledBy"
|
|
548
|
+
[ariaLive]="ariaLive"
|
|
549
|
+
[ariaSelected]="ariaSelected"
|
|
550
|
+
[ariaModal]="ariaModal"
|
|
551
|
+
[ariaValueMax]="ariaValueMax"
|
|
552
|
+
[ariaValueMin]="ariaValueMin"
|
|
553
|
+
[ariaValueNow]="ariaValueNow"
|
|
554
|
+
[ariaValueText]="ariaValueText"
|
|
555
|
+
[id]="id"
|
|
556
|
+
[role]="role"
|
|
557
|
+
>
|
|
558
|
+
<ng-content></ng-content>
|
|
559
|
+
</Pressable>
|
|
560
|
+
`,
|
|
561
|
+
})
|
|
562
|
+
export class TouchableWithoutFeedback implements IAngularTouchableWithoutFeedbackProps {
|
|
563
|
+
// delayPressIn/delayPressOut/minPressDuration ride the prop type for surface parity with the
|
|
564
|
+
// other two, but TouchableWithoutFeedback has no visual feedback, so nothing schedules off them
|
|
565
|
+
// (RN's TouchableWithoutFeedback is the same pure passthrough).
|
|
566
|
+
@Output() readonly press = new EventEmitter<ISymbioteEvent>();
|
|
567
|
+
@Output() readonly pressIn = new EventEmitter<ISymbioteEvent>();
|
|
568
|
+
@Output() readonly pressOut = new EventEmitter<ISymbioteEvent>();
|
|
569
|
+
@Output() readonly pressMove = new EventEmitter<ISymbioteEvent>();
|
|
570
|
+
@Output() readonly longPress = new EventEmitter<ISymbioteEvent>();
|
|
571
|
+
@Output() readonly hoverIn = new EventEmitter<ISymbioteEvent>();
|
|
572
|
+
@Output() readonly hoverOut = new EventEmitter<ISymbioteEvent>();
|
|
573
|
+
@Output() readonly accessibilityAction = new EventEmitter<ISymbioteEvent>();
|
|
574
|
+
@Output() readonly accessibilityTap = new EventEmitter<ISymbioteEvent>();
|
|
575
|
+
@Output() readonly magicTap = new EventEmitter<ISymbioteEvent>();
|
|
576
|
+
@Output() readonly accessibilityEscape = new EventEmitter<ISymbioteEvent>();
|
|
577
|
+
@Input() delayPressIn?: number;
|
|
578
|
+
@Input() delayPressOut?: number;
|
|
579
|
+
@Input() minPressDuration?: number;
|
|
580
|
+
@Input() style?: IStyleProp<IViewStyle>;
|
|
581
|
+
@Input() delayLongPress?: number;
|
|
582
|
+
@Input() delayHoverIn?: number;
|
|
583
|
+
@Input() delayHoverOut?: number;
|
|
584
|
+
@Input() disabled?: boolean;
|
|
585
|
+
@Input() cancelable?: boolean;
|
|
586
|
+
@Input() hitSlop?: IRectOffset;
|
|
587
|
+
@Input() pressRetentionOffset?: IRectOffset;
|
|
588
|
+
@Input() unstable_pressDelay?: number;
|
|
589
|
+
@Input() android_ripple?: IPressableAndroidRippleConfig;
|
|
590
|
+
@Input() android_disableSound?: boolean;
|
|
591
|
+
@Input() testID?: string;
|
|
592
|
+
@Input() nativeID?: string;
|
|
593
|
+
@Input() hasTVPreferredFocus?: boolean;
|
|
594
|
+
@Input() nextFocusDown?: number;
|
|
595
|
+
@Input() nextFocusForward?: number;
|
|
596
|
+
@Input() nextFocusLeft?: number;
|
|
597
|
+
@Input() nextFocusRight?: number;
|
|
598
|
+
@Input() nextFocusUp?: number;
|
|
599
|
+
@Input() accessible?: boolean;
|
|
600
|
+
@Input() accessibilityLabel?: string;
|
|
601
|
+
@Input() accessibilityHint?: string;
|
|
602
|
+
@Input() accessibilityRole?: IAccessibilityProps['accessibilityRole'];
|
|
603
|
+
@Input() accessibilityState?: IAccessibilityStateValue;
|
|
604
|
+
@Input() accessibilityValue?: IAccessibilityProps['accessibilityValue'];
|
|
605
|
+
@Input() accessibilityActions?: IAccessibilityProps['accessibilityActions'];
|
|
606
|
+
@Input() accessibilityLabelledBy?: string | string[];
|
|
607
|
+
@Input() importantForAccessibility?: IAccessibilityProps['importantForAccessibility'];
|
|
608
|
+
@Input() accessibilityLiveRegion?: IAccessibilityProps['accessibilityLiveRegion'];
|
|
609
|
+
@Input() screenReaderFocusable?: boolean;
|
|
610
|
+
@Input() accessibilityViewIsModal?: boolean;
|
|
611
|
+
@Input() accessibilityElementsHidden?: boolean;
|
|
612
|
+
@Input() accessibilityIgnoresInvertColors?: boolean;
|
|
613
|
+
@Input() accessibilityLanguage?: string;
|
|
614
|
+
@Input() accessibilityRespondsToUserInteraction?: boolean;
|
|
615
|
+
@Input() accessibilityShowsLargeContentViewer?: boolean;
|
|
616
|
+
@Input() accessibilityLargeContentTitle?: string;
|
|
617
|
+
@Input() ariaLabel?: string;
|
|
618
|
+
@Input() ariaBusy?: boolean;
|
|
619
|
+
@Input() ariaChecked?: boolean | 'mixed';
|
|
620
|
+
@Input() ariaDisabled?: boolean;
|
|
621
|
+
@Input() ariaExpanded?: boolean;
|
|
622
|
+
@Input() ariaHidden?: boolean;
|
|
623
|
+
@Input() ariaLabelledBy?: string;
|
|
624
|
+
@Input() ariaLive?: IAriaProps['aria-live'];
|
|
625
|
+
@Input() ariaSelected?: boolean;
|
|
626
|
+
@Input() ariaModal?: boolean;
|
|
627
|
+
@Input() ariaValueMax?: number;
|
|
628
|
+
@Input() ariaValueMin?: number;
|
|
629
|
+
@Input() ariaValueNow?: number;
|
|
630
|
+
@Input() ariaValueText?: string;
|
|
631
|
+
@Input() id?: string;
|
|
632
|
+
@Input() role?: IAriaProps['role'];
|
|
633
|
+
|
|
634
|
+
// This component's OWN host — the non-painting anchor `class="..."` at the use site resolves
|
|
635
|
+
// onto (see anchorHostStyle's doc comment) — NOT the Pressable one level down.
|
|
636
|
+
private readonly elementRef = inject(ElementRef);
|
|
637
|
+
|
|
638
|
+
// The anchor's class-derived style goes first, then the explicit style, so an explicit [style]
|
|
639
|
+
// still beats the ambient class.
|
|
640
|
+
get mergedStyle(): IStyleProp<IViewStyle> {
|
|
641
|
+
return [anchorStyleProp<IViewStyle>(this.elementRef), this.style];
|
|
642
|
+
}
|
|
643
|
+
}
|