@symbiote-native/navigation 3.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +10 -2
  2. package/build/angular/drawer/index.js +14 -6
  3. package/build/angular/tabs/index.js +18 -17
  4. package/build/core/render-drawer.js +4 -4
  5. package/build/core/render-tabs.js +5 -5
  6. package/build/react/drawer/index.js +1 -1
  7. package/build/react/tabs/index.js +2 -2
  8. package/build/solid/drawer/index.js +17 -14
  9. package/build/solid/tabs/index.js +3 -3
  10. package/build/svelte/drawer/index.svelte +23 -24
  11. package/build/svelte/registry-host.js +2 -2
  12. package/build/svelte/stack/index.svelte +5 -5
  13. package/build/svelte/tabs/index.svelte +9 -9
  14. package/build/vue/drawer/index.js +1 -1
  15. package/build/vue/tabs/index.js +3 -3
  16. package/build-ngc/angular/drawer/index.js +17 -9
  17. package/build-ngc/angular/drawer/index.js.map +1 -1
  18. package/build-ngc/angular/tabs/index.js +23 -22
  19. package/build-ngc/angular/tabs/index.js.map +1 -1
  20. package/build-ngc/core/render-drawer.js +4 -4
  21. package/build-ngc/core/render-drawer.js.map +1 -1
  22. package/build-ngc/core/render-tabs.js +5 -5
  23. package/build-ngc/core/render-tabs.js.map +1 -1
  24. package/package.json +14 -14
  25. package/src/angular/drawer/index.ts +13 -5
  26. package/src/angular/tabs/index.ts +18 -16
  27. package/src/core/render-drawer.ts +4 -4
  28. package/src/core/render-tabs.ts +5 -7
  29. package/src/react/drawer/index.ts +1 -1
  30. package/src/react/tabs/index.ts +3 -3
  31. package/src/solid/drawer/index.ts +18 -20
  32. package/src/solid/tabs/index.ts +3 -3
  33. package/src/svelte/drawer/index.svelte +23 -24
  34. package/src/svelte/registry-host.ts +2 -2
  35. package/src/svelte/stack/index.svelte +5 -5
  36. package/src/svelte/tabs/index.svelte +9 -9
  37. package/src/vue/drawer/index.ts +1 -1
  38. package/src/vue/tabs/index.ts +3 -3
package/README.md CHANGED
@@ -152,8 +152,16 @@ export class AppComponent {
152
152
  </script>
153
153
 
154
154
  <Stack bind:this={stackInstance} initialRouteName="Menu">
155
- <Screen name="Menu" component={MenuScreen} options={{ title: 'Navigation Demos' }} />
156
- <Screen name="Details" component={DetailsScreen} options={{ title: 'Details' }} />
155
+ <Screen
156
+ name="Menu"
157
+ component={MenuScreen}
158
+ options={{ title: 'Navigation Demos' }}
159
+ />
160
+ <Screen
161
+ name="Details"
162
+ component={DetailsScreen}
163
+ options={{ title: 'Details' }}
164
+ />
157
165
  </Stack>
158
166
  ```
159
167
 
@@ -21,7 +21,15 @@
21
21
  //
22
22
  // RESOLVED (see stack.ts's header, identical reasoning): `'Drawer'` has an `ANCHOR_HOST_COMPONENTS`
23
23
  // entry in `adapters/angular/src/renderer.ts`, so a real device build paints `<Drawer>` correctly
24
- // as a nested tag. `View`/`AnimatedView`, imported below, were already anchor-hosted.
24
+ // as a nested tag. `AnimatedView`, imported below, was already anchor-hosted.
25
+ //
26
+ // RAW NATIVE TAGS + NO_ERRORS_SCHEMA (see stack.ts's and tabs.ts's identical header note):
27
+ // `<view>` is a non-dashed raw tag, and `CUSTOM_ELEMENTS_SCHEMA` only relaxes tags containing a
28
+ // "-" (confirmed against `.vendors/angular/packages/compiler/src/schema/
29
+ // dom_element_schema_registry.ts`'s `hasElement`). The previous `View` import (`ViewHost`
30
+ // re-exported under that alias) never actually matched `<view>` here despite the identical
31
+ // selector — device-observed via `ngc`, not `tsc`/vitest — and was removed as dead (ngc's own
32
+ // NG8113 flagged it unused).
25
33
  //
26
34
  // DRAWER CONTENT PROJECTION: react/drawer.ts's `renderDrawerContent` is a render-PROP callback
27
35
  // (`(props) => ReactNode`) - per CLAUDE.md's <prop_types_split_agnostic_vs_per_adapter>, a
@@ -64,10 +72,10 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
64
72
  }
65
73
  return useValue ? value : void 0;
66
74
  };
67
- import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Input, QueryList, TemplateRef, computed, inject, signal, untracked, } from '@angular/core';
75
+ import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Input, NO_ERRORS_SCHEMA, QueryList, TemplateRef, computed, inject, signal, untracked, } from '@angular/core';
68
76
  import { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';
69
77
  import { PanResponder, dlog, flattenStyle, } from '@symbiote-native/engine';
70
- import { Animated, AnimatedView, SymbioteHostPropsDirective, View, WindowDimensionsService, } from '@symbiote-native/angular';
78
+ import { Animated, AnimatedView, SymbioteHostPropsDirective, WindowDimensionsService, } from '@symbiote-native/angular';
71
79
  import { DRAWER_DEFAULT_OVERLAY_COLOR, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_FOCUS, createInitialDrawerRouterState, createNavigationEmitter, diffFocusedRoute, drawerChildOrder, drawerRouterReducer, isDrawerAnimated, renderDrawer, resolveDragProgress, resolveDrawerGeometry, resolveDrawerSlotInterpolation, resolveSwipeIntent, shouldClaimDrawerSwipe, } from '../../core/index.js';
72
80
  import { NavigationScopeDirective } from '../navigation-scope.directive.js';
73
81
  import { DrawerScreenDirective } from '../drawer-screen.directive.js';
@@ -77,18 +85,18 @@ let Drawer = (() => {
77
85
  let _classDecorators = [Component({
78
86
  selector: 'Drawer',
79
87
  standalone: true,
88
+ schemas: [NO_ERRORS_SCHEMA],
80
89
  imports: [
81
90
  NgComponentOutlet,
82
91
  NgTemplateOutlet,
83
92
  NavigationScopeDirective,
84
93
  SymbioteHostPropsDirective,
85
- View,
86
94
  AnimatedView,
87
95
  ],
88
96
  changeDetection: ChangeDetectionStrategy.OnPush,
89
97
  template: `
90
98
  @if (state(); as currentState) {
91
- <View [style]="rootStyle()" [symbioteHostProps]="rootPanHandlers()">
99
+ <view [style]="rootStyle()" [symbioteHostProps]="rootPanHandlers()">
92
100
  @for (slot of slotOrder(); track slot) {
93
101
  @switch (slot) {
94
102
  @case ('content') {
@@ -132,7 +140,7 @@ let Drawer = (() => {
132
140
  }
133
141
  }
134
142
  }
135
- </View>
143
+ </view>
136
144
  }
137
145
  `,
138
146
  })];
@@ -6,11 +6,16 @@
6
6
  // implements ITabNavigatorHandle`) - plus the descriptor bridge (`symbiote-descriptor-outlet`,
7
7
  // `@symbiote-native/angular`) for the tab-bar leaf, exactly like Stack bridges its header config.
8
8
  // Unlike Stack, a bottom-tabs bar is a PURE-JS UI: it paints
9
- // ordinary `symbiote-view`/`symbiote-text` primitives via the shared render fn, so there is no
10
- // react-native-screens ViewConfig to register - Tab needs no `../register` import. Every tag this
11
- // template names (`View`, `symbiote-descriptor-outlet`) is a REAL imported Angular component (no
12
- // raw non-dashed native tag names the way stack.ts needs `NO_ERRORS_SCHEMA` for), so no loosened
13
- // schema is needed here at all.
9
+ // ordinary `view`/`text` primitives via the shared render fn, so there is no
10
+ // react-native-screens ViewConfig to register - Tab needs no `../register` import.
11
+ //
12
+ // RAW NATIVE TAGS + NO_ERRORS_SCHEMA (see stack.ts's identical header note): `<view>` is a
13
+ // non-dashed raw tag, and `CUSTOM_ELEMENTS_SCHEMA` only relaxes tags containing a "-" (confirmed
14
+ // against `.vendors/angular/packages/compiler/src/schema/dom_element_schema_registry.ts`'s
15
+ // `hasElement`) — it does NOT rescue this the way it does `symbiote-*`-prefixed selectors. The
16
+ // previous `View` import (`ViewHost` re-exported under that alias) never actually matched `<view>`
17
+ // here despite the identical selector — device-observed via `ngc`, not `tsc`/vitest — and was
18
+ // removed as dead (ngc's own NG8113 flagged it unused).
14
19
  //
15
20
  // RESOLVED (see stack.ts's header, identical reasoning): `'Tab'` has an `ANCHOR_HOST_COMPONENTS`
16
21
  // entry in `adapters/angular/src/renderer.ts`, so a real device build paints `<Tab>` correctly as
@@ -49,10 +54,10 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
49
54
  }
50
55
  return useValue ? value : void 0;
51
56
  };
52
- import { ChangeDetectionStrategy, Component, ContentChildren, Input, QueryList, signal, untracked, } from '@angular/core';
57
+ import { ChangeDetectionStrategy, Component, ContentChildren, Input, NO_ERRORS_SCHEMA, QueryList, signal, untracked, } from '@angular/core';
53
58
  import { NgComponentOutlet } from '@angular/common';
54
59
  import { dlog } from '@symbiote-native/engine';
55
- import { DescriptorOutlet, View } from '@symbiote-native/angular';
60
+ import { DescriptorOutlet } from '@symbiote-native/angular';
56
61
  import { NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_FOCUS, createInitialTabState, createNavigationEmitter, diffFocusedRoute, isFocusedRoute, reconcileTabRoutes, renderTabBar, tabRouterReducer, } from '../../core/index.js';
57
62
  import { NavigationScopeDirective } from '../navigation-scope.directive.js';
58
63
  import { TabScreenDirective } from '../tab-screen.directive.js';
@@ -63,16 +68,12 @@ let Tab = (() => {
63
68
  let _classDecorators = [Component({
64
69
  selector: 'Tab',
65
70
  standalone: true,
66
- imports: [
67
- NgComponentOutlet,
68
- NavigationScopeDirective,
69
- DescriptorOutlet,
70
- View,
71
- ],
71
+ schemas: [NO_ERRORS_SCHEMA],
72
+ imports: [NgComponentOutlet, NavigationScopeDirective, DescriptorOutlet],
72
73
  changeDetection: ChangeDetectionStrategy.OnPush,
73
74
  template: `
74
- <View [style]="rootStyle">
75
- <View [style]="contentStyle">
75
+ <view [style]="rootStyle">
76
+ <view [style]="contentStyle">
76
77
  @if (focusedRoute(); as route) {
77
78
  @if (componentForRoute(route); as component) {
78
79
  <ng-container
@@ -84,9 +85,9 @@ let Tab = (() => {
84
85
  </ng-container>
85
86
  }
86
87
  }
87
- </View>
88
+ </view>
88
89
  <symbiote-descriptor-outlet [node]="tabBarDescriptor()" />
89
- </View>
90
+ </view>
90
91
  `,
91
92
  })];
92
93
  let _classDescriptor;
@@ -68,14 +68,14 @@ function panelBaseStyle(options) {
68
68
  }
69
69
  export function renderDrawer(view, options) {
70
70
  const type = resolveDrawerType(options);
71
- const content = el('symbiote-view', { ...view.contentPassthrough, style: CONTENT_STYLE }, []);
72
- const panel = el('symbiote-view', {
71
+ const content = el('view', { ...view.contentPassthrough, style: CONTENT_STYLE }, []);
72
+ const panel = el('view', {
73
73
  ...view.panelPassthrough,
74
74
  style: [panelBaseStyle(options), view.drawerStyle],
75
75
  }, []);
76
76
  const slots = { content, panel };
77
77
  if (isDrawerOverlayVisible(options)) {
78
- slots.overlay = el('symbiote-view', {
78
+ slots.overlay = el('view', {
79
79
  ...view.overlayPassthrough,
80
80
  style: [OVERLAY_BASE_STYLE, { backgroundColor: view.overlayColor }],
81
81
  }, []);
@@ -87,5 +87,5 @@ export function renderDrawer(view, options) {
87
87
  return acc;
88
88
  }, []);
89
89
  const rootStyle = type === 'permanent' ? { ...ROOT_STYLE, flexDirection: 'row' } : ROOT_STYLE;
90
- return el('symbiote-view', { style: rootStyle }, children);
90
+ return el('view', { style: rootStyle }, children);
91
91
  }
@@ -1,6 +1,6 @@
1
1
  // TabBar: the render half (framework-agnostic). A bottom-tabs bar is a PURE-JS UI - unlike
2
2
  // Stack, which drives real native RNSScreen/RNSScreenStack views, this paints ordinary
3
- // `symbiote-view`/`symbiote-text` primitives, so it needs no react-native-screens ViewConfig
3
+ // `view`/`text` primitives, so it needs no react-native-screens ViewConfig
4
4
  // work at all (see the task brief in packages/navigation's skill notes). Mirrors renderSwitch's
5
5
  // shape: pure prop-driven functions building a `Descriptor` tree from pre-resolved view props;
6
6
  // the adapter supplies focus state, tint-color resolution inputs, and the press wiring via
@@ -72,7 +72,7 @@ function renderIcon(icon, color) {
72
72
  function renderBadge(badge) {
73
73
  if (badge === undefined)
74
74
  return undefined;
75
- return el('symbiote-view', { style: BADGE_STYLE }, [
75
+ return el('view', { style: BADGE_STYLE }, [
76
76
  txt({ style: BADGE_TEXT_STYLE }, [String(badge)]),
77
77
  ]);
78
78
  }
@@ -87,11 +87,11 @@ export function renderTabBarItem(item) {
87
87
  iconChildren.push(badge);
88
88
  const children = [];
89
89
  if (iconChildren.length > 0)
90
- children.push(el('symbiote-view', { style: ICON_WRAPPER_STYLE }, iconChildren));
90
+ children.push(el('view', { style: ICON_WRAPPER_STYLE }, iconChildren));
91
91
  children.push(txt({ style: { color, fontSize: TAB_LABEL_FONT_SIZE } }, [item.label]));
92
- return el('symbiote-view', { ...item.passthrough, style: TAB_ITEM_STYLE, accessibilityRole: 'tab' }, children, item.key);
92
+ return el('view', { ...item.passthrough, style: TAB_ITEM_STYLE, accessibilityRole: 'tab' }, children, item.key);
93
93
  }
94
94
  export function renderTabBar(view) {
95
95
  const items = view.items.map(renderTabBarItem);
96
- return el('symbiote-view', { ...view.passthrough, style: [TAB_BAR_STYLE, view.style] }, items);
96
+ return el('view', { ...view.passthrough, style: [TAB_BAR_STYLE, view.style] }, items);
97
97
  }
@@ -290,7 +290,7 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
290
290
  const drawerChildren = order
291
291
  .map(renderSlot)
292
292
  .filter((element) => element !== null);
293
- return createElement('symbiote-view', { style: root.props.style, ...panResponder.panHandlers }, ...drawerChildren);
293
+ return createElement('view', { style: root.props.style, ...panResponder.panHandlers }, ...drawerChildren);
294
294
  });
295
295
  export const Drawer = Object.assign(DrawerImpl, { Screen: DrawerScreen });
296
296
  // --- Explicit gap list vs the real react-native-gesture-handler + react-native-reanimated
@@ -4,7 +4,7 @@
4
4
  // router state, useId for route-key generation, useImperativeHandle for the jumpTo/setParams
5
5
  // handle - plus the descriptor bridge for the tab-bar leaf, exactly like Stack bridges its header
6
6
  // config (react/stack.ts). Unlike Stack, a bottom-tabs bar is a PURE-JS UI: it paints ordinary
7
- // `symbiote-view`/`symbiote-text` primitives via the shared render fn, so there is no
7
+ // `view`/`text` primitives via the shared render fn, so there is no
8
8
  // react-native-screens ViewConfig to register here - Tab needs no `../register` import.
9
9
  import { createElement, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useMemo, useState, } from 'react';
10
10
  import { descriptorToReact } from '@symbiote-native/react';
@@ -135,6 +135,6 @@ const TabImpl = forwardRef((props, forwardedRef) => {
135
135
  },
136
136
  }, createElement(focusedEntry.component))
137
137
  : null;
138
- return createElement('symbiote-view', { style: TAB_ROOT_STYLE }, createElement('symbiote-view', { style: TAB_CONTENT_STYLE }, content), tabBar);
138
+ return createElement('view', { style: TAB_ROOT_STYLE }, createElement('view', { style: TAB_CONTENT_STYLE }, content), tabBar);
139
139
  });
140
140
  export const Tab = Object.assign(TabImpl, { Screen: TabScreen });
@@ -24,7 +24,7 @@
24
24
  // value: §4 of the same rules file. A value snapshot would freeze the drawer's own content at the
25
25
  // state it was built with, and re-invoking it from inside a tracked scope would replace the whole
26
26
  // panel subtree mid-gesture.
27
- import { createEffect, createMemo, createSignal, mergeProps, onCleanup, untrack, } from 'solid-js';
27
+ import { createEffect, createMemo, createSignal, onCleanup, untrack, } from 'solid-js';
28
28
  import { Animated, createWindowDimensions } from '@symbiote-native/solid';
29
29
  // createComponent from solid-js, insert from the renderer - see stack/index.ts's note.
30
30
  import { createComponent } from 'solid-js';
@@ -342,21 +342,24 @@ function DrawerImpl(props) {
342
342
  insert(node, children);
343
343
  return node;
344
344
  }
345
- // ONE source, never a spread followed by an explicit prop: mergeProps takes the first
346
- // NON-undefined value scanning back-to-front, so a later `undefined` silently loses to an
347
- // earlier value (.claude/rules/solid-descriptor-bridge.md §6). Collapsing to a single bag
348
- // removes the question. mergeProps still earns its place - it wraps the function source in a
349
- // memo and hands Animated.View a reactive proxy, which is what keeps the slot's props live
350
- // without rebuilding the node.
351
- return createComponent(Animated.View, mergeProps(() => ({
345
+ // ONE source, never a spread followed by an explicit prop: mergeProps took the first
346
+ // NON-undefined value scanning back-to-front, so a later `undefined` silently lost to an
347
+ // earlier one (.claude/rules/solid-descriptor-bridge.md §6). A single bag removes the
348
+ // question, and the thunk is what keeps the slot's props live without rebuilding the node.
349
+ //
350
+ // No Animated.View: the engine resolves an AnimatedNode written into any prop of any host
351
+ // node, so the interpolation in `animatedStyle` binds from a plain `view`.
352
+ const animated = hostElement('view', () => ({
352
353
  ...slotDescriptor(slot).props,
353
354
  style: [slotDescriptor(slot).props.style, animatedStyle(slot)],
354
- get children() {
355
- return slotChildren(slot);
356
- },
357
- })));
355
+ }));
356
+ // An ACCESSOR, not a value: the slot's children are the focused screen, which mounts after
357
+ // this node is built. Reading once here yields the pre-mount slot and the screen never
358
+ // arrives — where the branch above may read eagerly, because its children are already built.
359
+ insert(animated, () => slotChildren(slot));
360
+ return animated;
358
361
  }
359
- const root = hostElement('symbiote-view', () => ({
362
+ const root = hostElement('view', () => ({
360
363
  ...rootDescriptor().props,
361
364
  ...panResponder.panHandlers,
362
365
  }));
@@ -367,7 +370,7 @@ function DrawerImpl(props) {
367
370
  const current = shape();
368
371
  return untrack(() => buildDrawer(current));
369
372
  });
370
- const host = hostElement('symbiote-view', () => ({ style: { flex: 1 } }));
373
+ const host = hostElement('view', () => ({ style: { flex: 1 } }));
371
374
  insert(host, drawer);
372
375
  return createComponent(ScreenCollectorProvider, {
373
376
  value: collector,
@@ -3,7 +3,7 @@
3
3
  // every other adapter; here Solid supplies the lifecycle - a signal for the dispatched router
4
4
  // state, a callback `ref` for the jumpTo/setParams handle - plus the descriptor bridge for the
5
5
  // tab-bar leaf. Unlike Stack, a bottom-tabs bar is a PURE-JS UI painting ordinary
6
- // `symbiote-view`/`symbiote-text` primitives, so there is no react-native-screens ViewConfig to
6
+ // `view`/`text` primitives, so there is no react-native-screens ViewConfig to
7
7
  // register here.
8
8
  //
9
9
  // TWO SOLID-ONLY REBUILD BOUNDARIES, both invisible in every other adapter:
@@ -209,11 +209,11 @@ function TabImpl(props) {
209
209
  const found = state().routes.find(route => route.key === routeKey);
210
210
  return found ?? { key: routeKey, name: '', params: undefined };
211
211
  }
212
- const contentHost = hostElement('symbiote-view', () => ({
212
+ const contentHost = hostElement('view', () => ({
213
213
  style: TAB_CONTENT_STYLE,
214
214
  }));
215
215
  insert(contentHost, content);
216
- const root = hostElement('symbiote-view', () => ({ style: TAB_ROOT_STYLE }));
216
+ const root = hostElement('view', () => ({ style: TAB_ROOT_STYLE }));
217
217
  // ONE array insert rather than two: a second `insert` on the same parent would find the first
218
218
  // child already there and REPLACE it (solid-js/universal's insertExpression), while an array is
219
219
  // reconciled by identity - contentHost keeps its node, only the bar is swapped when it rebuilds.
@@ -35,10 +35,6 @@
35
35
  IPanResponderGestureState,
36
36
  ISymbioteEvent,
37
37
  } from '@symbiote-native/engine';
38
- // The ONLY import from the adapter's main barrel: `Animated.View` is a compiled `.svelte`
39
- // component, so unlike PanResponder/Dimensions/AnimatedValue (pure engine re-exports, taken
40
- // from the engine directly here) it has no `.svelte`-free home to import from.
41
- import { Animated } from '@symbiote-native/svelte';
42
38
  import {
43
39
  DRAWER_DEFAULT_OVERLAY_COLOR,
44
40
  NAVIGATION_EVENT_BLUR,
@@ -471,16 +467,18 @@
471
467
  {@const descriptor = slotDescriptors.content}
472
468
  {#if descriptor !== undefined}
473
469
  {#if contentStyle !== undefined}
474
- <Animated.View
475
- {...descriptor.props}
476
- style={[descriptor.props.style, contentStyle]}
470
+ <view
471
+ p={{
472
+ ...descriptor.props,
473
+ style: [descriptor.props.style, contentStyle],
474
+ }}
477
475
  >
478
476
  {@render screenContent()}
479
- </Animated.View>
477
+ </view>
480
478
  {:else}
481
- <symbiote-view p={descriptor.props}>
479
+ <view p={descriptor.props}>
482
480
  {@render screenContent()}
483
- </symbiote-view>
481
+ </view>
484
482
  {/if}
485
483
  {/if}
486
484
  {/snippet}
@@ -489,12 +487,14 @@
489
487
  {@const descriptor = slotDescriptors.overlay}
490
488
  {#if descriptor !== undefined}
491
489
  {#if overlayStyle !== undefined}
492
- <Animated.View
493
- {...descriptor.props}
494
- style={[descriptor.props.style, overlayStyle]}
490
+ <view
491
+ p={{
492
+ ...descriptor.props,
493
+ style: [descriptor.props.style, overlayStyle],
494
+ }}
495
495
  />
496
496
  {:else}
497
- <symbiote-view p={descriptor.props} />
497
+ <view p={descriptor.props} />
498
498
  {/if}
499
499
  {/if}
500
500
  {/snippet}
@@ -503,32 +503,31 @@
503
503
  {@const descriptor = slotDescriptors.panel}
504
504
  {#if descriptor !== undefined}
505
505
  {#if panelStyle !== undefined}
506
- <Animated.View
507
- {...descriptor.props}
508
- style={[descriptor.props.style, panelStyle]}
506
+ <view
507
+ p={{ ...descriptor.props, style: [descriptor.props.style, panelStyle] }}
509
508
  >
510
509
  {@render drawerContent?.({
511
510
  state,
512
511
  descriptors,
513
512
  navigation: handle,
514
513
  })}
515
- </Animated.View>
514
+ </view>
516
515
  {:else}
517
- <symbiote-view p={descriptor.props}>
516
+ <view p={descriptor.props}>
518
517
  {@render drawerContent?.({
519
518
  state,
520
519
  descriptors,
521
520
  navigation: handle,
522
521
  })}
523
- </symbiote-view>
522
+ </view>
524
523
  {/if}
525
524
  {/if}
526
525
  {/snippet}
527
526
 
528
- <symbiote-view p={rootProps}>
529
- <symbiote-text p={SCREEN_REGISTRY_HOST_PROPS}>
527
+ <view p={rootProps}>
528
+ <text p={SCREEN_REGISTRY_HOST_PROPS}>
530
529
  {@render children?.()}
531
- </symbiote-text>
530
+ </text>
532
531
  {#each order as slot (slot)}
533
532
  {#if slot === 'content'}
534
533
  {@render contentSlot()}
@@ -538,7 +537,7 @@
538
537
  {@render panelSlot()}
539
538
  {/if}
540
539
  {/each}
541
- </symbiote-view>
540
+ </view>
542
541
 
543
542
  <!-- --- Explicit gap list vs the real react-native-gesture-handler + react-native-reanimated
544
543
  @react-navigation/drawer (confirmed against its current docs, mirrored verbatim from the
@@ -12,11 +12,11 @@
12
12
  //
13
13
  // therefore compiles to `from_tree([marker, ' ', marker])`, and each ' ' becomes an RCTRawText
14
14
  // engine node parented to whatever host tag holds the `{@render children?.()}` call. Inside a
15
- // plain `symbiote-view` that is the invalid "text outside a <Text> component" shape; inside
15
+ // plain `view` that is the invalid "text outside a <text> component" shape; inside
16
16
  // RNSScreenStack it is worse, since react-native-screens' native side expects only RNSScreen
17
17
  // children there.
18
18
  //
19
- // So the markers are rendered inside a zero-size `symbiote-text` instead: raw text inside an
19
+ // So the markers are rendered inside a zero-size `text` instead: raw text inside an
20
20
  // RCTText is LEGAL, which turns the hazard from a device crash into a no-op and makes it
21
21
  // structurally impossible rather than a rule app authors have to remember. The cost is one
22
22
  // collapsed, non-interactive RCTText per navigator.
@@ -15,7 +15,7 @@
15
15
  // HOW SCREENS ARE DISCOVERED: not by reading `children`, which Svelte hands over as an opaque
16
16
  // Snippet - the markers register themselves through the context collector (../screen-registry.ts)
17
17
  // while the snippet renders, and the route list derives from that. The snippet is rendered
18
- // inside a collapsed `symbiote-text` (../registry-host.ts) so whitespace between two markers
18
+ // inside a collapsed `text` (../registry-host.ts) so whitespace between two markers
19
19
  // can never become an illegal raw-text child of a native view.
20
20
 
21
21
  // Route keys must be unique per Stack INSTANCE (Svelte has no useId); a module counter is the
@@ -233,10 +233,10 @@
233
233
  }
234
234
  </script>
235
235
 
236
- <symbiote-view p={STACK_ROOT_PROPS}>
237
- <symbiote-text p={SCREEN_REGISTRY_HOST_PROPS}>
236
+ <view p={STACK_ROOT_PROPS}>
237
+ <text p={SCREEN_REGISTRY_HOST_PROPS}>
238
238
  {@render children?.()}
239
- </symbiote-text>
239
+ </text>
240
240
  <svelte:element
241
241
  this={RNS_SCREEN_STACK_VIEW_NAME}
242
242
  {@attach hostProps(stackProps)}
@@ -258,4 +258,4 @@
258
258
  {/if}
259
259
  {/each}
260
260
  </svelte:element>
261
- </symbiote-view>
261
+ </view>
@@ -4,8 +4,8 @@
4
4
  // with the React/Vue/Angular entries; here Svelte supplies the lifecycle - `$state.raw` for the
5
5
  // router (its twin of useReducer), a module counter for route-key generation, `export
6
6
  // function`s for the jumpTo/setParams handle - plus the Descriptor bridge for the tab-bar leaf.
7
- // Unlike Stack, a bottom-tabs bar is a PURE-JS UI: it paints ordinary `symbiote-view`/
8
- // `symbiote-text` primitives via the shared render fn, so there is no react-native-screens
7
+ // Unlike Stack, a bottom-tabs bar is a PURE-JS UI: it paints ordinary `view`/
8
+ // `text` primitives via the shared render fn, so there is no react-native-screens
9
9
  // ViewConfig to register here - Tab needs no `../../register` import.
10
10
  //
11
11
  // Screens are discovered through the context collector (../screen-registry.ts), not by reading
@@ -253,17 +253,17 @@
253
253
  });
254
254
  </script>
255
255
 
256
- <symbiote-view p={TAB_ROOT_PROPS}>
257
- <symbiote-text p={SCREEN_REGISTRY_HOST_PROPS}>
256
+ <view p={TAB_ROOT_PROPS}>
257
+ <text p={SCREEN_REGISTRY_HOST_PROPS}>
258
258
  {@render children?.()}
259
- </symbiote-text>
260
- <symbiote-view p={TAB_CONTENT_PROPS}>
259
+ </text>
260
+ <view p={TAB_CONTENT_PROPS}>
261
261
  {#if focusedScreen !== undefined}
262
262
  {@const FocusedComponent = focusedScreen.component}
263
263
  <NavigationScope value={focusedScreen.scope}>
264
264
  <FocusedComponent />
265
265
  </NavigationScope>
266
266
  {/if}
267
- </symbiote-view>
268
- <symbiote-view p={tabBar.props} bind:this={tabBarHost} />
269
- </symbiote-view>
267
+ </view>
268
+ <view p={tabBar.props} bind:this={tabBarHost} />
269
+ </view>
@@ -391,7 +391,7 @@ const DrawerImpl = defineComponent((_props, { attrs: rawAttrs, slots, expose })
391
391
  const drawerChildren = order
392
392
  .map(renderSlot)
393
393
  .filter((element) => element !== null);
394
- return h('symbiote-view', { style: root.props.style, ...panResponder.panHandlers }, drawerChildren);
394
+ return h('view', { style: root.props.style, ...panResponder.panHandlers }, drawerChildren);
395
395
  };
396
396
  }, { name: 'Drawer', inheritAttrs: false });
397
397
  export const Drawer = Object.assign(DrawerImpl, { Screen: DrawerScreen });
@@ -4,7 +4,7 @@
4
4
  // router state (Vue's twin of useReducer), useId for route-key generation, expose() for the
5
5
  // jumpTo/setParams handle - plus the descriptor bridge for the tab-bar leaf, like Stack's header
6
6
  // config (stack.ts). Unlike Stack, a bottom-tabs bar is a PURE-JS UI: it paints ordinary
7
- // `symbiote-view`/`symbiote-text` primitives via the shared render fn, so there is no
7
+ // `view`/`text` primitives via the shared render fn, so there is no
8
8
  // react-native-screens ViewConfig to register here - Tab needs no `../register` import.
9
9
  import { defineComponent, h, nextTick, onUnmounted, shallowRef, useId, } from '@vue/runtime-core';
10
10
  import { descriptorToVue, normalizeVueAttrs } from '@symbiote-native/vue';
@@ -226,8 +226,8 @@ const TabImpl = defineComponent((_props, { attrs: rawAttrs, slots, expose }) =>
226
226
  // NavigationScope provided just above (useRoute / useTabNavigation).
227
227
  () => h(focusedEntry.component))
228
228
  : null;
229
- return h('symbiote-view', { style: TAB_ROOT_STYLE }, [
230
- h('symbiote-view', { style: TAB_CONTENT_STYLE }, content === null ? [] : [content]),
229
+ return h('view', { style: TAB_ROOT_STYLE }, [
230
+ h('view', { style: TAB_CONTENT_STYLE }, content === null ? [] : [content]),
231
231
  tabBar,
232
232
  ]);
233
233
  };
@@ -21,7 +21,15 @@
21
21
  //
22
22
  // RESOLVED (see stack.ts's header, identical reasoning): `'Drawer'` has an `ANCHOR_HOST_COMPONENTS`
23
23
  // entry in `adapters/angular/src/renderer.ts`, so a real device build paints `<Drawer>` correctly
24
- // as a nested tag. `View`/`AnimatedView`, imported below, were already anchor-hosted.
24
+ // as a nested tag. `AnimatedView`, imported below, was already anchor-hosted.
25
+ //
26
+ // RAW NATIVE TAGS + NO_ERRORS_SCHEMA (see stack.ts's and tabs.ts's identical header note):
27
+ // `<view>` is a non-dashed raw tag, and `CUSTOM_ELEMENTS_SCHEMA` only relaxes tags containing a
28
+ // "-" (confirmed against `.vendors/angular/packages/compiler/src/schema/
29
+ // dom_element_schema_registry.ts`'s `hasElement`). The previous `View` import (`ViewHost`
30
+ // re-exported under that alias) never actually matched `<view>` here despite the identical
31
+ // selector — device-observed via `ngc`, not `tsc`/vitest — and was removed as dead (ngc's own
32
+ // NG8113 flagged it unused).
25
33
  //
26
34
  // DRAWER CONTENT PROJECTION: react/drawer.ts's `renderDrawerContent` is a render-PROP callback
27
35
  // (`(props) => ReactNode`) - per CLAUDE.md's <prop_types_split_agnostic_vs_per_adapter>, a
@@ -30,10 +38,10 @@
30
38
  // context object, NOT a callback @Input(): `<Drawer><ng-template #drawerContent let-ctx>...
31
39
  // {{ ctx.state }}...</ng-template></Drawer>`, read here via `@ContentChild('drawerContent', {read:
32
40
  // TemplateRef})`.
33
- import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Input, QueryList, TemplateRef, computed, inject, signal, untracked, } from '@angular/core';
41
+ import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Input, NO_ERRORS_SCHEMA, QueryList, TemplateRef, computed, inject, signal, untracked, } from '@angular/core';
34
42
  import { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';
35
43
  import { PanResponder, dlog, flattenStyle, } from '@symbiote-native/engine';
36
- import { Animated, AnimatedView, SymbioteHostPropsDirective, View, WindowDimensionsService, } from '@symbiote-native/angular';
44
+ import { Animated, AnimatedView, SymbioteHostPropsDirective, WindowDimensionsService, } from '@symbiote-native/angular';
37
45
  import { DRAWER_DEFAULT_OVERLAY_COLOR, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_FOCUS, createInitialDrawerRouterState, createNavigationEmitter, diffFocusedRoute, drawerChildOrder, drawerRouterReducer, isDrawerAnimated, renderDrawer, resolveDragProgress, resolveDrawerGeometry, resolveDrawerSlotInterpolation, resolveSwipeIntent, shouldClaimDrawerSwipe, } from '../../core';
38
46
  import { NavigationScopeDirective } from '../navigation-scope.directive';
39
47
  import { DrawerScreenDirective } from '../drawer-screen.directive';
@@ -359,7 +367,7 @@ export class Drawer {
359
367
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: Drawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
360
368
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: Drawer, isStandalone: true, selector: "Drawer", inputs: { initialRouteName: "initialRouteName", drawerStyle: "drawerStyle", drawerType: "drawerType", drawerPosition: "drawerPosition", drawerWidth: "drawerWidth", overlayColor: "overlayColor", swipeEnabled: "swipeEnabled", swipeEdgeWidth: "swipeEdgeWidth", swipeMinDistance: "swipeMinDistance", swipeMinVelocity: "swipeMinVelocity" }, queries: [{ propertyName: "drawerContentTemplate", first: true, predicate: ["drawerContent"], descendants: true, read: TemplateRef }, { propertyName: "drawerScreenChildren", predicate: DrawerScreenDirective }], usesOnChanges: true, ngImport: i0, template: `
361
369
  @if (state(); as currentState) {
362
- <View [style]="rootStyle()" [symbioteHostProps]="rootPanHandlers()">
370
+ <view [style]="rootStyle()" [symbioteHostProps]="rootPanHandlers()">
363
371
  @for (slot of slotOrder(); track slot) {
364
372
  @switch (slot) {
365
373
  @case ('content') {
@@ -403,27 +411,27 @@ export class Drawer {
403
411
  }
404
412
  }
405
413
  }
406
- </View>
414
+ </view>
407
415
  }
408
- `, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NavigationScopeDirective, selector: "[symbioteNavigationScope]", inputs: ["symbioteNavigationScope", "navigation", "emitter"] }, { kind: "directive", type: SymbioteHostPropsDirective, selector: "[symbioteHostProps]", inputs: ["symbioteHostProps"], exportAs: ["symbioteHost"] }, { kind: "component", type: View, selector: "symbiote-view, View" }, { kind: "component", type: AnimatedView, selector: "AnimatedView, symbiote-animated-view", inputs: ["style", "animatedProps", "passthroughAnimatedPropExplicitValues"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
416
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NavigationScopeDirective, selector: "[symbioteNavigationScope]", inputs: ["symbioteNavigationScope", "navigation", "emitter"] }, { kind: "directive", type: SymbioteHostPropsDirective, selector: "[symbioteHostProps]", inputs: ["symbioteHostProps"], exportAs: ["symbioteHost"] }, { kind: "component", type: AnimatedView, selector: "AnimatedView, symbiote-animated-view", inputs: ["style", "testID", "animatedProps", "passthroughAnimatedPropExplicitValues"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
409
417
  }
410
418
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: Drawer, decorators: [{
411
419
  type: Component,
412
420
  args: [{
413
421
  selector: 'Drawer',
414
422
  standalone: true,
423
+ schemas: [NO_ERRORS_SCHEMA],
415
424
  imports: [
416
425
  NgComponentOutlet,
417
426
  NgTemplateOutlet,
418
427
  NavigationScopeDirective,
419
428
  SymbioteHostPropsDirective,
420
- View,
421
429
  AnimatedView,
422
430
  ],
423
431
  changeDetection: ChangeDetectionStrategy.OnPush,
424
432
  template: `
425
433
  @if (state(); as currentState) {
426
- <View [style]="rootStyle()" [symbioteHostProps]="rootPanHandlers()">
434
+ <view [style]="rootStyle()" [symbioteHostProps]="rootPanHandlers()">
427
435
  @for (slot of slotOrder(); track slot) {
428
436
  @switch (slot) {
429
437
  @case ('content') {
@@ -467,7 +475,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
467
475
  }
468
476
  }
469
477
  }
470
- </View>
478
+ </view>
471
479
  }
472
480
  `,
473
481
  }]