@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,172 @@
|
|
|
1
|
+
import { ChangeDetectorRef, Directive, ElementRef, inject, Input, Renderer2, } from '@angular/core';
|
|
2
|
+
import { flattenStyle, isSymbioteNode, } from '@symbiote-native/engine';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* A composed Angular component (Pressable, SafeAreaView, ScrollView, ...) is created as a
|
|
6
|
+
* non-painting ANCHOR host (`ANCHOR_HOST_COMPONENTS` in renderer.ts) so it doesn't paint an
|
|
7
|
+
* extra native view over its own template's real content. `class="..."`/`[class.x]`/`[ngClass]`
|
|
8
|
+
* at the component's use site ALWAYS resolves through the renderer's addClass/removeClass onto
|
|
9
|
+
* that anchor — Angular gives no `@Input()` interception hook for `class` the way it does for
|
|
10
|
+
* `[style]` (which is why `style` alone was declared as an `@Input()` in the first place, see
|
|
11
|
+
* `SymbiotePrimitiveHost` above) — so the anchor ends up holding the fully-resolved class-derived
|
|
12
|
+
* style (`routeProp`'s `commitClassStyle` already wrote it to `anchor.props.style`) while the
|
|
13
|
+
* REAL native node the component's own template creates never sees it.
|
|
14
|
+
*
|
|
15
|
+
* Call this from a composed component's own `hostProps`/style getter and merge the result AHEAD
|
|
16
|
+
* of its own explicit `style` @Input, e.g. `style: [anchorHostStyle(this.elementRef),
|
|
17
|
+
* this.resolvedStyle]` — array order matters: `flattenStyle`'s later-wins collapse is what makes
|
|
18
|
+
* an explicit `[style]` on the component still beat its ambient class, mirroring the
|
|
19
|
+
* class-loses-to-explicit-style cascade `commitClassStyle` already enforces for a direct
|
|
20
|
+
* primitive. `this.elementRef` must be this component's OWN injected `ElementRef` (its anchor
|
|
21
|
+
* host), not a `@ViewChild` into its template's inner primitive.
|
|
22
|
+
*
|
|
23
|
+
* Skipping this call for a new `ANCHOR_HOST_COMPONENTS` entry compiles clean under `tsc` AND a
|
|
24
|
+
* real `ngc` AOT build — no type error, no template error — it just silently drops `class="..."`
|
|
25
|
+
* forever; only a device/simulator render (or a committed-node style assertion) catches it. See
|
|
26
|
+
* the `angular-adapter` skill §21 for the device-confirmed incident and the full checklist.
|
|
27
|
+
*/
|
|
28
|
+
export function anchorHostStyle(elementRef) {
|
|
29
|
+
const node = elementRef.nativeElement;
|
|
30
|
+
return isSymbioteNode(node) ? node.props.style : undefined;
|
|
31
|
+
}
|
|
32
|
+
// anchorHostStyle returns `unknown` (it reads whatever already resolved onto the anchor node's
|
|
33
|
+
// props bag); a style prop's fields are all optional so any object structurally satisfies it —
|
|
34
|
+
// this narrows just enough (falsy-per-IStyleProp, or an object/array) to fold it into a
|
|
35
|
+
// strictly-typed IStyleProp<T> array without an `as` cast, for a composed component whose own
|
|
36
|
+
// inner primitive declares a real `@Input() style: IStyleProp<SomeConcreteStyle>` (e.g.
|
|
37
|
+
// TouchableOpacity's Pressable, Button's TouchableOpacity) rather than the loosely-typed
|
|
38
|
+
// `symbioteHostProps` bag most composed components merge anchorHostStyle into directly.
|
|
39
|
+
function isStyleValue(value) {
|
|
40
|
+
return (value === undefined ||
|
|
41
|
+
value === null ||
|
|
42
|
+
value === false ||
|
|
43
|
+
value === '' ||
|
|
44
|
+
typeof value === 'object');
|
|
45
|
+
}
|
|
46
|
+
export function anchorStyleProp(elementRef) {
|
|
47
|
+
const value = anchorHostStyle(elementRef);
|
|
48
|
+
return isStyleValue(value) ? value : undefined;
|
|
49
|
+
}
|
|
50
|
+
function isRecord(value) {
|
|
51
|
+
return typeof value === 'object' && value !== null;
|
|
52
|
+
}
|
|
53
|
+
function shallowStyleEqual(a, b) {
|
|
54
|
+
const aKeys = Object.keys(a);
|
|
55
|
+
if (aKeys.length !== Object.keys(b).length)
|
|
56
|
+
return false;
|
|
57
|
+
return aKeys.every(key => a[key] === b[key]);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* `anchorHostStyle` must be re-read on every check (a bare `class="x"` with no matching
|
|
61
|
+
* `[style]` binding never appears in Angular's `SimpleChanges`/dirty-check inputs, so nothing
|
|
62
|
+
* else signals "the anchor's class-derived style may have changed"). But `flattenStyle([...])`
|
|
63
|
+
* always allocates a FRESH object, even when its content is byte-for-byte identical to last
|
|
64
|
+
* time — and a windowed list component (FlatList/VirtualizedList/SectionList/
|
|
65
|
+
* VirtualizedSectionList) binds its resolved style into a structural-directive-bound `@Input()`
|
|
66
|
+
* chain where a fresh reference on an UNRELATED CD pass is mistaken for a real change, which
|
|
67
|
+
* reschedules ANOTHER CD tick (`VListOutletDirective`'s `context` `@Input()` calling
|
|
68
|
+
* `markForCheck()`) — free-running forever. See the `flat-list-array-style.test.ts` regression
|
|
69
|
+
* this fixes (and the near-identical `lastRecompute` dedup guard in `virtualized-list/index.ts`,
|
|
70
|
+
* which this mirrors at the style-merge call site instead of a whole recompute step). Returns
|
|
71
|
+
* `previous` unchanged when the freshly-flattened merge is shallow-equal to it, so a downstream
|
|
72
|
+
* `@Input() style` binding sees NO change and skips its own update on an unrelated tick.
|
|
73
|
+
*/
|
|
74
|
+
export function stableAnchorStyle(elementRef, explicitStyle, previous) {
|
|
75
|
+
const next = flattenStyle([anchorHostStyle(elementRef), explicitStyle]);
|
|
76
|
+
return isRecord(previous) && shallowStyleEqual(previous, next) ? previous : next;
|
|
77
|
+
}
|
|
78
|
+
const ON_PREFIX = /^on[A-Z]/;
|
|
79
|
+
/**
|
|
80
|
+
* Base for all Angular primitive host components (`symbiote-view`, `symbiote-text`, ...).
|
|
81
|
+
* RN's `StyleProp` can be an object, an array, nested arrays, falsy entries, and Animated
|
|
82
|
+
* values. Angular's raw `[style]` binding on a custom element routes through the CSS style
|
|
83
|
+
* engine (`setStyle` per key), which crashes on numeric array keys. By declaring `style` as
|
|
84
|
+
* an Angular `@Input()` on a known component, we intercept it here and forward a flattened
|
|
85
|
+
* style object through `Renderer2.setProperty`, bypassing Angular's CSS styling path.
|
|
86
|
+
*
|
|
87
|
+
* Other props (source, pointerEvents, ...) are intentionally *not* declared as inputs.
|
|
88
|
+
* Angular then treats them as host property bindings and still dispatches them through the
|
|
89
|
+
* custom renderer's `setProperty`, so the engine's `routeProp` handles them as usual.
|
|
90
|
+
*/
|
|
91
|
+
export class SymbiotePrimitiveHost {
|
|
92
|
+
renderer = inject(Renderer2);
|
|
93
|
+
elementRef = inject(ElementRef);
|
|
94
|
+
style;
|
|
95
|
+
/**
|
|
96
|
+
* The underlying engine host node (public instance). Exposed so `findNodeHandle` can resolve
|
|
97
|
+
* an Angular template ref (`#ref`) on a primitive host to its native reactTag.
|
|
98
|
+
*/
|
|
99
|
+
get nativeElement() {
|
|
100
|
+
return this.elementRef.nativeElement;
|
|
101
|
+
}
|
|
102
|
+
ngOnChanges(changes) {
|
|
103
|
+
if (!('style' in changes))
|
|
104
|
+
return;
|
|
105
|
+
const value = this.style === undefined ? undefined : flattenStyle(this.style);
|
|
106
|
+
this.renderer.setProperty(this.elementRef.nativeElement, 'style', value);
|
|
107
|
+
}
|
|
108
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SymbiotePrimitiveHost, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
109
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.4", type: SymbiotePrimitiveHost, isStandalone: true, inputs: { style: "style" }, usesOnChanges: true, ngImport: i0 });
|
|
110
|
+
}
|
|
111
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SymbiotePrimitiveHost, decorators: [{
|
|
112
|
+
type: Directive
|
|
113
|
+
}], propDecorators: { style: [{
|
|
114
|
+
type: Input
|
|
115
|
+
}] } });
|
|
116
|
+
/**
|
|
117
|
+
* Applies a whole resolved props record (a shared `renderX(...).props` bag) onto a host
|
|
118
|
+
* element via `Renderer2.setProperty`, one call per key. Angular templates compile bindings
|
|
119
|
+
* ahead of time — there is no `v-bind="obj"` equivalent for a custom element — so a component
|
|
120
|
+
* whose props come from a shared render function would otherwise have to declare every key as
|
|
121
|
+
* its own static `[prop]="hostProps['x']"` binding. This generalizes the pattern
|
|
122
|
+
* `SwitchHostPropsDirective` proved first: `<symbiote-x [symbioteHostProps]="hostProps" #ref="symbioteHost">`,
|
|
123
|
+
* with `ref.node` exposing the native element for any imperative follow-up call.
|
|
124
|
+
*/
|
|
125
|
+
export class SymbioteHostPropsDirective {
|
|
126
|
+
renderer = inject(Renderer2);
|
|
127
|
+
elementRef = inject(ElementRef);
|
|
128
|
+
// The directive lives in its HOST component's template, so its injected ChangeDetectorRef IS
|
|
129
|
+
// that component's own view detector — the one thing that can refresh it (see wrapCallback).
|
|
130
|
+
cdr = inject(ChangeDetectorRef);
|
|
131
|
+
get node() {
|
|
132
|
+
return this.elementRef.nativeElement;
|
|
133
|
+
}
|
|
134
|
+
set symbioteHostProps(props) {
|
|
135
|
+
for (const [key, value] of Object.entries(props)) {
|
|
136
|
+
this.renderer.setProperty(this.elementRef.nativeElement, key, this.wrapCallback(key, value));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// A flat-bag `onX` callback (responder negotiation, onLongPress, …) is invoked by the engine's
|
|
140
|
+
// event dispatch — a plain JS call, entirely outside Angular. In Angular 20 a component compiles
|
|
141
|
+
// as a SignalView (not CheckAlways), so a plain (non-signal) state mutation inside such a callback
|
|
142
|
+
// does NOT dirty the view's reactive consumer, and the scheduler's root detectChanges() will NOT
|
|
143
|
+
// descend into it (a Global pass only refreshes CheckAlways / Dirty / RefreshView views) — the
|
|
144
|
+
// "pan does nothing" bug on a nested component. `markForCheck()` flags THIS component's view AND
|
|
145
|
+
// all its ancestors with RefreshView (which survives the descent) and notifies the CD scheduler,
|
|
146
|
+
// so the next root tick repaints the mutation. It targets the directive's injecting view
|
|
147
|
+
// (`_cdRefInjectingView`, i.e. the host component), unlike `detectChanges()` which acts on a
|
|
148
|
+
// resolved `_lView` that is NOT the host component here. The Angular twin of what React/Vue get
|
|
149
|
+
// for free (setState / proxy reactivity). See the `angular-adapter` skill §17.
|
|
150
|
+
wrapCallback(key, value) {
|
|
151
|
+
if (!ON_PREFIX.test(key) || typeof value !== 'function')
|
|
152
|
+
return value;
|
|
153
|
+
const handler = value;
|
|
154
|
+
return (...args) => {
|
|
155
|
+
const result = handler(...args);
|
|
156
|
+
this.cdr.markForCheck();
|
|
157
|
+
return result;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SymbioteHostPropsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
161
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.4", type: SymbioteHostPropsDirective, isStandalone: true, selector: "[symbioteHostProps]", inputs: { symbioteHostProps: "symbioteHostProps" }, exportAs: ["symbioteHost"], ngImport: i0 });
|
|
162
|
+
}
|
|
163
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: SymbioteHostPropsDirective, decorators: [{
|
|
164
|
+
type: Directive,
|
|
165
|
+
args: [{
|
|
166
|
+
selector: '[symbioteHostProps]',
|
|
167
|
+
standalone: true,
|
|
168
|
+
exportAs: 'symbioteHost',
|
|
169
|
+
inputs: ['symbioteHostProps'],
|
|
170
|
+
}]
|
|
171
|
+
}] });
|
|
172
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/primitives/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type IRootTag, type SymbioteSurface } from '@symbiote-native/engine';
|
|
2
|
+
import { type Type } from '@angular/core';
|
|
3
|
+
export interface IMountOptions {
|
|
4
|
+
initialProps?: object;
|
|
5
|
+
wrapperComponent?: Type<unknown>;
|
|
6
|
+
}
|
|
7
|
+
export declare function mount(rootTag: IRootTag, rootComponent: Type<unknown>, options?: IMountOptions): SymbioteSurface;
|
|
8
|
+
export declare function unmount(rootTag: IRootTag): void;
|
|
9
|
+
declare global {
|
|
10
|
+
var RN$stopSurface: ((surfaceId: number) => void) | undefined;
|
|
11
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// Mount an Angular app onto a Fabric surface. The native host hands us a rootTag; we
|
|
2
|
+
// create a surface and bootstrap a standalone Angular component WITHOUT platform-browser
|
|
3
|
+
// (no DOM) — createEnvironmentInjector + createComponent over @angular/core only, with our
|
|
4
|
+
// SymbioteRendererFactory provided so Angular drives the engine, which commits into
|
|
5
|
+
// nativeFabricUIManager; RN's own renderer never in the path. Angular twin of
|
|
6
|
+
// adapters/vue/src/render.ts. See the `angular-adapter` skill (§2 bootstrap).
|
|
7
|
+
import { createElement as createEngineElement, createSurface, disposeRoot, dlog, toPublicInstance, } from '@symbiote-native/engine';
|
|
8
|
+
import { descriptorFor } from '@symbiote-native/components';
|
|
9
|
+
import { ApplicationRef, createComponent, createEnvironmentInjector, DOCUMENT, RendererFactory2, ɵINJECTOR_SCOPE as INJECTOR_SCOPE, ɵprovideZonelessChangeDetectionInternal as provideZonelessChangeDetectionInternal, } from '@angular/core';
|
|
10
|
+
import { SymbioteRendererFactory } from './renderer';
|
|
11
|
+
import { ColorSchemeService, WindowDimensionsService } from './services';
|
|
12
|
+
// The two FFI-edge casts of this adapter, both confined here to bootstrap. Angular's core
|
|
13
|
+
// types model a browser: the injector parent is a non-null EnvironmentInjector, the host is
|
|
14
|
+
// a DOM Element. Our root has neither shape — a null parent IS a root injector, and the host
|
|
15
|
+
// is a SymbioteSurface (or, for a wrapped AppRegistry root, a plain engine node) the
|
|
16
|
+
// SymbioteRenderer (not the DOM) consumes. These are the sanctioned I/O-edge casts where our
|
|
17
|
+
// objects cross into Angular's web-typed API; revisit if Angular ever exposes a cast-free
|
|
18
|
+
// host. Nothing else in the adapter casts.
|
|
19
|
+
function rootInjectorParent() {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function asAngularHost(hostNode) {
|
|
23
|
+
// Angular's locateHostElement reads hostElement.tagName even when a concrete hostElement
|
|
24
|
+
// is supplied. The host container is given Angular the tiny DOM-shaped field it probes
|
|
25
|
+
// without changing the renderer target.
|
|
26
|
+
Object.defineProperty(hostNode, 'tagName', {
|
|
27
|
+
configurable: true,
|
|
28
|
+
value: 'symbiote-root',
|
|
29
|
+
});
|
|
30
|
+
return hostNode;
|
|
31
|
+
}
|
|
32
|
+
// A bare `symbiote-view` node, created directly through the engine (bypassing Angular's own
|
|
33
|
+
// createElement, which only resolves KNOWN symbiote primitives, never an arbitrary component's
|
|
34
|
+
// selector — see SymbioteRenderer.createElement). Used as the AppRegistry root's host when a
|
|
35
|
+
// wrapperComponentProvider is set: Angular has no hostElement-less bootstrap for our renderer
|
|
36
|
+
// (it would try `renderer.createElement(rootComponent.selector)`, which throws for anything
|
|
37
|
+
// that isn't one of our primitives), so the root needs an explicit host too, one we then hand
|
|
38
|
+
// to the wrapper as projectable content.
|
|
39
|
+
function createDetachedViewHost() {
|
|
40
|
+
const descriptor = descriptorFor('View');
|
|
41
|
+
return toPublicInstance(createEngineElement(descriptor.component, descriptor.isText));
|
|
42
|
+
}
|
|
43
|
+
function applyInputs(cmpRef, initialProps) {
|
|
44
|
+
if (initialProps === undefined)
|
|
45
|
+
return;
|
|
46
|
+
for (const [key, value] of Object.entries(initialProps)) {
|
|
47
|
+
cmpRef.setInput(key, value);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// One Angular app per surface, so a surface can be torn down (unmount) or cleanly
|
|
51
|
+
// re-mounted on the same rootTag: the bridgeless host stops and restarts a surface on Fast
|
|
52
|
+
// Refresh and on lifecycle/focus changes, reusing the rootTag.
|
|
53
|
+
const apps = new Map();
|
|
54
|
+
function teardown(rootTag) {
|
|
55
|
+
const app = apps.get(rootTag);
|
|
56
|
+
if (app === undefined)
|
|
57
|
+
return;
|
|
58
|
+
app.rootRef?.destroy();
|
|
59
|
+
app.cmpRef.destroy();
|
|
60
|
+
app.injector.destroy();
|
|
61
|
+
apps.delete(rootTag);
|
|
62
|
+
disposeRoot(rootTag);
|
|
63
|
+
}
|
|
64
|
+
export function mount(rootTag, rootComponent, options) {
|
|
65
|
+
// A re-mount on a live rootTag starts clean; otherwise the stale app double-drives the surface.
|
|
66
|
+
teardown(rootTag);
|
|
67
|
+
const surface = createSurface(rootTag);
|
|
68
|
+
const injector = createEnvironmentInjector([
|
|
69
|
+
{
|
|
70
|
+
provide: RendererFactory2,
|
|
71
|
+
useValue: new SymbioteRendererFactory(surface),
|
|
72
|
+
},
|
|
73
|
+
{ provide: DOCUMENT, useValue: { head: surface, body: surface } },
|
|
74
|
+
// createEnvironmentInjector with a null parent gives this injector scope
|
|
75
|
+
// {'environment'} only (see EnvironmentNgModuleRefAdapter), so providedIn:'root'
|
|
76
|
+
// tokens — ApplicationRef included — never resolve on their own (R3Injector.get
|
|
77
|
+
// walks up looking for an injector whose `scopes` contains 'root', and a null
|
|
78
|
+
// parent means that search always dead-ends in NullInjector). platform-browser's
|
|
79
|
+
// BROWSER_MODULE_PROVIDERS solves this the same way for real DOM apps: it hands
|
|
80
|
+
// { provide: INJECTOR_SCOPE, useValue: 'root' } to its OWN app-level providers, and
|
|
81
|
+
// R3Injector's constructor reads that provider and self-tags this.scopes with
|
|
82
|
+
// 'root'. We do the same here — no PlatformRef, no DOM, just this one provider.
|
|
83
|
+
{ provide: INJECTOR_SCOPE, useValue: 'root' },
|
|
84
|
+
// Supplies the real ChangeDetectionSchedulerImpl (microtask-batched, self-scheduling
|
|
85
|
+
// via ApplicationRef.afterTick) + NoopNgZone + ZONELESS_ENABLED: true — the exact
|
|
86
|
+
// bundle internalCreateApplication() uses. With ApplicationRef reachable (see above),
|
|
87
|
+
// there is no more reason for a hand-rolled scheduler: it replaces our old
|
|
88
|
+
// unconditional `rootView.detectChanges(); cmpView.detectChanges()` (which force-ran
|
|
89
|
+
// BOTH root views on every tick regardless of cause) with Angular's own tick(), which
|
|
90
|
+
// only enters an attached view when something actually marked it (RefreshView / Dirty
|
|
91
|
+
// consumer / HasChildViewsToRefresh). NOTE: this does NOT stop the root's own template
|
|
92
|
+
// from re-running on a plain press or `ChangeDetectorRef.markForCheck()` anywhere in
|
|
93
|
+
// the tree — `markViewDirty` (which both native (event) bindings and `markForCheck()`
|
|
94
|
+
// go through, see SymbioteHostPropsDirective) unconditionally sets RefreshView on
|
|
95
|
+
// EVERY ancestor up to the root; that is fundamental, unavoidable Angular zoneless
|
|
96
|
+
// behavior, true in every Angular app, not something this swap changes. What DOES
|
|
97
|
+
// still protect a sibling branch from an unrelated press is a genuine child
|
|
98
|
+
// `@Component` boundary — SignalView-compiled children are skip-eligible regardless of
|
|
99
|
+
// this scheduler (see the `angular-adapter` skill §20 for the full investigation,
|
|
100
|
+
// including the test that disproved the stronger claim before it shipped).
|
|
101
|
+
...provideZonelessChangeDetectionInternal(),
|
|
102
|
+
ColorSchemeService,
|
|
103
|
+
WindowDimensionsService,
|
|
104
|
+
], rootInjectorParent());
|
|
105
|
+
// hostElement = the surface: the component's template content commits straight into the
|
|
106
|
+
// surface with no wrapper view, the engine wrapping surface.children in its synthetic flex
|
|
107
|
+
// root — the Angular equivalent of Vue's `app.mount(surface)`.
|
|
108
|
+
let cmpRef;
|
|
109
|
+
let rootRef;
|
|
110
|
+
if (options?.wrapperComponent === undefined) {
|
|
111
|
+
cmpRef = createComponent(rootComponent, {
|
|
112
|
+
environmentInjector: injector,
|
|
113
|
+
hostElement: asAngularHost(surface),
|
|
114
|
+
});
|
|
115
|
+
applyInputs(cmpRef, options?.initialProps);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// The root gets its own host node from the renderer (createComponent without a
|
|
119
|
+
// hostElement) but is not attached to the surface directly; it is handed to the
|
|
120
|
+
// wrapper as projectable content instead, so only the wrapper needs a real host.
|
|
121
|
+
const rootHost = asAngularHost(createDetachedViewHost());
|
|
122
|
+
rootRef = createComponent(rootComponent, {
|
|
123
|
+
environmentInjector: injector,
|
|
124
|
+
hostElement: rootHost,
|
|
125
|
+
});
|
|
126
|
+
applyInputs(rootRef, options.initialProps);
|
|
127
|
+
cmpRef = createComponent(options.wrapperComponent, {
|
|
128
|
+
environmentInjector: injector,
|
|
129
|
+
hostElement: asAngularHost(surface),
|
|
130
|
+
projectableNodes: [[rootHost]],
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// Attach both root views to ApplicationRef so its own tick() (via the real
|
|
134
|
+
// ChangeDetectionSchedulerImpl provided above) drives them from here on — no manual
|
|
135
|
+
// ChangeDetectorRef juggling needed. markForCheck anywhere in the tree now notifies
|
|
136
|
+
// the real scheduler, which batches a microtask and calls appRef.tick() itself.
|
|
137
|
+
const appRef = injector.get(ApplicationRef);
|
|
138
|
+
appRef.attachView(cmpRef.hostView);
|
|
139
|
+
if (rootRef !== undefined) {
|
|
140
|
+
appRef.attachView(rootRef.hostView);
|
|
141
|
+
}
|
|
142
|
+
dlog(`angular mount root=${rootTag}`);
|
|
143
|
+
appRef.tick(); // first paint
|
|
144
|
+
surface.requestCommit();
|
|
145
|
+
apps.set(rootTag, { cmpRef, rootRef, injector });
|
|
146
|
+
return surface;
|
|
147
|
+
}
|
|
148
|
+
// Tear down a surface by rootTag: the public pair of `mount`, and the JS half of the
|
|
149
|
+
// bridgeless `RN$stopSurface` contract (see installStopSurfaceGlobal).
|
|
150
|
+
export function unmount(rootTag) {
|
|
151
|
+
dlog(`angular unmount root=${rootTag}`);
|
|
152
|
+
teardown(rootTag);
|
|
153
|
+
}
|
|
154
|
+
function installStopSurfaceGlobal() {
|
|
155
|
+
globalThis.RN$stopSurface = (surfaceId) => {
|
|
156
|
+
unmount(surfaceId);
|
|
157
|
+
};
|
|
158
|
+
dlog('installed global.RN$stopSurface');
|
|
159
|
+
}
|
|
160
|
+
installStopSurfaceGlobal();
|
|
161
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SymbioteSurface, type ISymbioteNode } from '@symbiote-native/engine';
|
|
2
|
+
import type { Renderer2, RendererFactory2, RendererType2 } from '@angular/core';
|
|
3
|
+
type IHostNode = ISymbioteNode;
|
|
4
|
+
type IHostElement = ISymbioteNode | SymbioteSurface;
|
|
5
|
+
export declare function registerComposedComponent(selector: string): void;
|
|
6
|
+
export declare class SymbioteRenderer implements Renderer2 {
|
|
7
|
+
private readonly surface;
|
|
8
|
+
readonly data: Record<string, unknown>;
|
|
9
|
+
destroyNode: ((node: ISymbioteNode) => void) | null;
|
|
10
|
+
constructor(surface: SymbioteSurface);
|
|
11
|
+
destroy(): void;
|
|
12
|
+
createElement(name: string): IHostNode;
|
|
13
|
+
createComment(): IHostNode;
|
|
14
|
+
createText(value: string): IHostNode;
|
|
15
|
+
appendChild(parent: IHostElement | null, newChild: IHostNode): void;
|
|
16
|
+
insertBefore(parent: IHostElement | null, newChild: IHostNode, refChild: IHostNode | null): void;
|
|
17
|
+
removeChild(_parent: IHostElement | null, oldChild: IHostNode): void;
|
|
18
|
+
parentNode(node: IHostNode): IHostElement | null;
|
|
19
|
+
nextSibling(node: IHostNode): IHostNode | null;
|
|
20
|
+
selectRootElement(selectorOrNode: string | IHostElement): IHostElement;
|
|
21
|
+
setAttribute(el: IHostElement, name: string, value: string): void;
|
|
22
|
+
removeAttribute(el: IHostElement, name: string): void;
|
|
23
|
+
private readonly classTokens;
|
|
24
|
+
addClass(el: IHostElement, name: string): void;
|
|
25
|
+
removeClass(el: IHostElement, name: string): void;
|
|
26
|
+
setStyle(el: IHostElement, style: string, value: unknown): void;
|
|
27
|
+
removeStyle(el: IHostElement, style: string): void;
|
|
28
|
+
setProperty(el: IHostElement, name: string, value: unknown): void;
|
|
29
|
+
setValue(node: IHostNode, value: string): void;
|
|
30
|
+
listen(target: unknown, eventName: string, callback: (event: unknown) => boolean | void): () => void;
|
|
31
|
+
}
|
|
32
|
+
export declare class SymbioteRendererFactory implements RendererFactory2 {
|
|
33
|
+
private readonly surface;
|
|
34
|
+
private renderer;
|
|
35
|
+
constructor(surface: SymbioteSurface);
|
|
36
|
+
createRenderer(_hostElement: unknown, _type: RendererType2 | null): Renderer2;
|
|
37
|
+
}
|
|
38
|
+
export {};
|