@symbiote-native/vue 0.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +28 -13
  2. package/babel-jsx.cjs +52 -0
  3. package/build/components/activity-indicator-props.d.ts +5 -0
  4. package/build/components/activity-indicator-props.js +1 -0
  5. package/build/components/button-props.d.ts +5 -0
  6. package/build/components/button-props.js +1 -0
  7. package/build/components/flat-list/index.d.ts +3 -3
  8. package/build/components/flat-list/index.js +2 -2
  9. package/build/components/image-background-props.d.ts +7 -0
  10. package/build/components/image-background-props.js +1 -0
  11. package/build/components/image-props.d.ts +5 -0
  12. package/build/components/image-props.js +5 -0
  13. package/build/components/{input-accessory-view.d.ts → input-accessory-view-props.d.ts} +1 -3
  14. package/build/components/input-accessory-view-props.js +5 -0
  15. package/build/components/keyboard-avoiding-view.js +3 -3
  16. package/build/components/modal/index.js +1 -1
  17. package/build/components/pressable-props.d.ts +29 -0
  18. package/build/components/pressable-props.js +12 -0
  19. package/build/components/refresh-control-props.d.ts +16 -0
  20. package/build/components/refresh-control-props.js +9 -0
  21. package/build/components/safe-area-view-props.d.ts +6 -0
  22. package/build/components/safe-area-view-props.js +5 -0
  23. package/build/components/scroll-view/{shared.d.ts → scroll-view-props.d.ts} +4 -27
  24. package/build/components/scroll-view/scroll-view-props.js +1 -0
  25. package/build/components/section-list/index.d.ts +3 -3
  26. package/build/components/switch/switch-props.d.ts +6 -0
  27. package/build/components/switch/switch-props.js +1 -0
  28. package/build/components/text-input/text-input-props.d.ts +5 -0
  29. package/build/components/text-input/text-input-props.js +1 -0
  30. package/build/components/text-props.d.ts +24 -0
  31. package/build/components/text-props.js +6 -0
  32. package/build/components/touchable-native-feedback-props.d.ts +6 -0
  33. package/build/components/touchable-native-feedback-props.js +1 -0
  34. package/build/components/touchable-props.d.ts +15 -0
  35. package/build/components/touchable-props.js +1 -0
  36. package/build/components/touchable-without-feedback-props.d.ts +3 -0
  37. package/build/components/touchable-without-feedback-props.js +1 -0
  38. package/build/components/view-props.d.ts +29 -0
  39. package/build/components/view-props.js +5 -0
  40. package/build/components/virtualized-list/index.d.ts +3 -3
  41. package/build/components/virtualized-list/index.js +42 -37
  42. package/build/components/virtualized-section-list/index.d.ts +3 -3
  43. package/build/composables/use-raw-attrs.d.ts +1 -0
  44. package/build/composables/use-raw-attrs.js +26 -0
  45. package/build/descriptor-to-vue.js +2 -2
  46. package/build/host-instance/index.js +4 -5
  47. package/build/index.d.ts +25 -27
  48. package/build/index.js +35 -15
  49. package/build/intrinsic-elements.d.ts +19 -0
  50. package/build/intrinsic-elements.js +1 -0
  51. package/build/jsx-runtime.d.ts +67 -0
  52. package/build/jsx-runtime.js +1 -0
  53. package/build/modules/animated/create-animated-component.d.ts +1 -1
  54. package/build/modules/animated/create-animated-component.js +18 -4
  55. package/build/modules/animated/index.d.ts +3 -1
  56. package/build/modules/animated/index.js +20 -19
  57. package/build/modules/image/index.d.ts +3 -0
  58. package/build/modules/image/index.js +13 -0
  59. package/build/register.d.ts +1 -0
  60. package/build/register.js +15 -0
  61. package/build/renderer/index.js +112 -12
  62. package/build/runtime-helpers/index.d.ts +14 -1
  63. package/build/runtime-helpers/index.js +250 -9
  64. package/build/utils/normalize-attrs.d.ts +1 -0
  65. package/build/utils/normalize-attrs.js +21 -15
  66. package/intrinsic-tags.cjs +52 -0
  67. package/metro-css-parser.cjs +2 -1
  68. package/metro-vue-transformer.cjs +83 -13
  69. package/package.json +33 -8
  70. package/build/components/activity-indicator/index.android.d.ts +0 -4
  71. package/build/components/activity-indicator/index.android.js +0 -10
  72. package/build/components/activity-indicator/index.d.ts +0 -1
  73. package/build/components/activity-indicator/index.ios.d.ts +0 -4
  74. package/build/components/activity-indicator/index.ios.js +0 -10
  75. package/build/components/activity-indicator/index.js +0 -4
  76. package/build/components/activity-indicator/shared.d.ts +0 -8
  77. package/build/components/activity-indicator/shared.js +0 -48
  78. package/build/components/button.d.ts +0 -14
  79. package/build/components/button.js +0 -59
  80. package/build/components/image-background.d.ts +0 -9
  81. package/build/components/image-background.js +0 -103
  82. package/build/components/image.d.ts +0 -9
  83. package/build/components/image.js +0 -90
  84. package/build/components/input-accessory-view.js +0 -41
  85. package/build/components/pressable.d.ts +0 -58
  86. package/build/components/pressable.js +0 -214
  87. package/build/components/refresh-control.d.ts +0 -20
  88. package/build/components/refresh-control.js +0 -47
  89. package/build/components/safe-area-view.d.ts +0 -8
  90. package/build/components/safe-area-view.js +0 -33
  91. package/build/components/scroll-view/index.android.d.ts +0 -4
  92. package/build/components/scroll-view/index.android.js +0 -64
  93. package/build/components/scroll-view/index.d.ts +0 -1
  94. package/build/components/scroll-view/index.ios.d.ts +0 -4
  95. package/build/components/scroll-view/index.ios.js +0 -17
  96. package/build/components/scroll-view/index.js +0 -4
  97. package/build/components/scroll-view/shared.js +0 -271
  98. package/build/components/scroll-view/sticky-header.d.ts +0 -7
  99. package/build/components/scroll-view/sticky-header.js +0 -208
  100. package/build/components/switch/index.android.d.ts +0 -12
  101. package/build/components/switch/index.android.js +0 -13
  102. package/build/components/switch/index.d.ts +0 -2
  103. package/build/components/switch/index.ios.d.ts +0 -12
  104. package/build/components/switch/index.ios.js +0 -11
  105. package/build/components/switch/index.js +0 -5
  106. package/build/components/switch/shared.d.ts +0 -23
  107. package/build/components/switch/shared.js +0 -126
  108. package/build/components/text-input/index.d.ts +0 -24
  109. package/build/components/text-input/index.js +0 -242
  110. package/build/components/touchable-native-feedback.d.ts +0 -24
  111. package/build/components/touchable-native-feedback.js +0 -77
  112. package/build/components/touchable.d.ts +0 -50
  113. package/build/components/touchable.js +0 -278
  114. package/build/components.d.ts +0 -51
  115. package/build/components.js +0 -29
@@ -70,7 +70,6 @@ export type IVirtualizedListEmits<ItemT> = {
70
70
  }) => void;
71
71
  };
72
72
  export declare const VirtualizedList: new <ItemT>(props: (IVirtualizedListProps<ItemT> & ({} | {
73
- onRefresh?: (() => any) | undefined;
74
73
  onViewableItemsChanged?: ((info: IViewableItemsChangedInfo<ItemT>) => any) | undefined;
75
74
  onEndReached?: ((info: {
76
75
  distanceFromEnd: number;
@@ -78,13 +77,13 @@ export declare const VirtualizedList: new <ItemT>(props: (IVirtualizedListProps<
78
77
  onStartReached?: ((info: {
79
78
  distanceFromStart: number;
80
79
  }) => any) | undefined;
80
+ onRefresh?: (() => any) | undefined;
81
81
  onScrollToIndexFailed?: ((info: {
82
82
  index: number;
83
83
  highestMeasuredFrameIndex: number;
84
84
  averageItemLength: number;
85
85
  }) => any) | undefined;
86
86
  })) & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps) => import("vue").CreateComponentPublicInstanceWithMixins<IVirtualizedListProps<ItemT> & ({} | {
87
- onRefresh?: (() => any) | undefined;
88
87
  onViewableItemsChanged?: ((info: IViewableItemsChangedInfo<ItemT>) => any) | undefined;
89
88
  onEndReached?: ((info: {
90
89
  distanceFromEnd: number;
@@ -92,6 +91,7 @@ export declare const VirtualizedList: new <ItemT>(props: (IVirtualizedListProps<
92
91
  onStartReached?: ((info: {
93
92
  distanceFromStart: number;
94
93
  }) => any) | undefined;
94
+ onRefresh?: (() => any) | undefined;
95
95
  onScrollToIndexFailed?: ((info: {
96
96
  index: number;
97
97
  highestMeasuredFrameIndex: number;
@@ -105,7 +105,6 @@ export declare const VirtualizedList: new <ItemT>(props: (IVirtualizedListProps<
105
105
  M: {};
106
106
  Defaults: {};
107
107
  }, (IVirtualizedListProps<ItemT> & {}) | (IVirtualizedListProps<ItemT> & {
108
- onRefresh?: (() => any) | undefined;
109
108
  onViewableItemsChanged?: ((info: IViewableItemsChangedInfo<ItemT>) => any) | undefined;
110
109
  onEndReached?: ((info: {
111
110
  distanceFromEnd: number;
@@ -113,6 +112,7 @@ export declare const VirtualizedList: new <ItemT>(props: (IVirtualizedListProps<
113
112
  onStartReached?: ((info: {
114
113
  distanceFromStart: number;
115
114
  }) => any) | undefined;
115
+ onRefresh?: (() => any) | undefined;
116
116
  onScrollToIndexFailed?: ((info: {
117
117
  index: number;
118
118
  highestMeasuredFrameIndex: number;
@@ -27,10 +27,8 @@
27
27
  // scroll commands would silently no-op. The folded listState is a PLAIN object (not reactive) —
28
28
  // mutating it never triggers Vue; the `version` ref is bumped when a transition changes render state.
29
29
  import { computed, defineComponent, getCurrentInstance, h, isVNode, onBeforeUnmount, ref, shallowRef, watch, } from '@vue/runtime-core';
30
- import { DEFAULT_END_REACHED_THRESHOLD, DEFAULT_INITIAL_NUM_TO_RENDER, DEFAULT_MAX_TO_RENDER_PER_BATCH, DEFAULT_START_REACHED_THRESHOLD, DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, DEFAULT_WINDOW_SIZE, EMPTY_OFFSET, FIRST_INDEX, INVERTED_X_STYLE, INVERTED_Y_STYLE, buildListPlan, buildViewabilityPairs, createInitialListState, isSeparatorGapInRange, listEffectSignature, readLayoutLength, readLayoutOffset, readScrollOffset, reduceList, resolveItemKey, } from '@symbiote-native/components';
31
- import { dlog, } from '@symbiote-native/engine';
32
- import { ScrollView } from '../scroll-view';
33
- import { RefreshControl } from '../refresh-control.js';
30
+ import { DEFAULT_END_REACHED_THRESHOLD, DEFAULT_INITIAL_NUM_TO_RENDER, DEFAULT_MAX_TO_RENDER_PER_BATCH, DEFAULT_START_REACHED_THRESHOLD, DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, DEFAULT_WINDOW_SIZE, EMPTY_OFFSET, FIRST_INDEX, INVERTED_X_STYLE, INVERTED_Y_STYLE, buildListPlan, buildScrollViewHandle, buildViewabilityPairs, createInitialListState, isSeparatorGapInRange, listEffectSignature, readLayoutLength, readLayoutOffset, readScrollOffset, reduceList, resolveItemKey, } from '@symbiote-native/components';
31
+ import { dlog, isSymbioteNode, } from '@symbiote-native/engine';
34
32
  import { normalizeVueAttrs } from '../../utils/normalize-attrs.js';
35
33
  import { componentFromSlot } from '../../utils/slots-to-render-props.js';
36
34
  // The typed inputs VirtualizedList reads off `props`; everything else (raw scroll, keyboard*,
@@ -74,9 +72,6 @@ const EMIT_KEYS = [
74
72
  function isHandler(value) {
75
73
  return typeof value === 'function';
76
74
  }
77
- function isRecord(value) {
78
- return typeof value === 'object' && value !== null && !Array.isArray(value);
79
- }
80
75
  function isComponent(value) {
81
76
  return (typeof value === 'function' || (typeof value === 'object' && value !== null));
82
77
  }
@@ -118,9 +113,6 @@ function renderSeparatorElement(component, leadingItem, trailingItem, overrides)
118
113
  };
119
114
  return h(component, props);
120
115
  }
121
- function isScrollViewHandle(value) {
122
- return isRecord(value) && typeof value.scrollTo === 'function';
123
- }
124
116
  export const VirtualizedList = defineComponent((props, { attrs, expose, emit, slots, }) => {
125
117
  // Bumped when a transition changes render-relevant state, so the `metrics` computed and the
126
118
  // render fn re-run (listState is plain, non-reactive, so mutating it triggers nothing itself).
@@ -129,13 +121,17 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
129
121
  // The offset we are imperatively driving native to. A fresh object identity each push so the
130
122
  // commit path re-applies it even when the numeric value repeats. undefined = none pending.
131
123
  const commandedOffset = ref(undefined);
132
- // shallowRef, NOT ref: the ScrollView handle closes over the engine scroll node, reached by
133
- // identity through the engine's WeakMap mirror. A deep ref would proxy the object and every
134
- // imperative scroll (scrollToOffset/Index/…) would miss the node and silently no-op.
135
- const scrollHandle = shallowRef(null);
136
- const setScrollHandle = (instance) => {
137
- scrollHandle.value = isScrollViewHandle(instance) ? instance : null;
124
+ // shallowRef, NOT ref: `<scroll-view>` is a tag now, so its `ref` hands back the raw engine
125
+ // node directly, reached by identity through the engine's WeakMap mirror. A deep ref would
126
+ // proxy the object and every imperative scroll (scrollToOffset/Index/…) would miss the node
127
+ // and silently no-op.
128
+ const scrollNodeRef = shallowRef(null);
129
+ const setScrollNodeRef = (el) => {
130
+ scrollNodeRef.value = isSymbioteNode(el) ? el : null;
138
131
  };
132
+ // Built once: `getNode` is lazy, read on every call, so this stays valid across the ref
133
+ // transitioning from null to the committed node.
134
+ const scrollHandle = buildScrollViewHandle(() => scrollNodeRef.value);
139
135
  // The five list events are emits, so Vue strips their onX listeners from $attrs. Detect listener
140
136
  // presence off the instance's own vnode props (what the parent passed), exactly like FlatList, so
141
137
  // an emit bridge is wired ONLY when the consumer actually listens (preserving the RefreshControl /
@@ -243,10 +239,13 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
243
239
  const targetOffset = p.horizontal
244
240
  ? { x: clamped, y: EMPTY_OFFSET }
245
241
  : { x: EMPTY_OFFSET, y: clamped };
246
- const handle = scrollHandle.value;
247
- if (handle !== null) {
242
+ if (scrollNodeRef.value !== null) {
248
243
  dlog(`Vue VirtualizedList scrollTo offset=${clamped} animated=${animated} (horizontal=${p.horizontal})`);
249
- handle.scrollTo({ x: targetOffset.x, y: targetOffset.y, animated });
244
+ scrollHandle.scrollTo({
245
+ x: targetOffset.x,
246
+ y: targetOffset.y,
247
+ animated,
248
+ });
250
249
  return;
251
250
  }
252
251
  dlog(`Vue VirtualizedList scrollTo offset=${clamped} pending-ref`);
@@ -411,12 +410,12 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
411
410
  dispatch({ kind: 'scroll-to-end', animated: params?.animated ?? true });
412
411
  },
413
412
  flashScrollIndicators: () => {
414
- scrollHandle.value?.flashScrollIndicators();
413
+ scrollHandle.flashScrollIndicators();
415
414
  },
416
- getNativeScrollRef: () => scrollHandle.value,
417
- getScrollableNode: () => scrollHandle.value,
418
- getScrollResponder: () => scrollHandle.value,
419
- getScrollNode: () => scrollHandle.value?.getScrollNode() ?? null,
415
+ getNativeScrollRef: () => scrollNodeRef.value !== null ? scrollHandle : null,
416
+ getScrollableNode: () => scrollNodeRef.value !== null ? scrollHandle : null,
417
+ getScrollResponder: () => scrollNodeRef.value !== null ? scrollHandle : null,
418
+ getScrollNode: () => scrollNodeRef.value,
420
419
  recordInteraction: () => {
421
420
  dispatch({ kind: 'record-interaction' });
422
421
  },
@@ -451,13 +450,13 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
451
450
  : undefined;
452
451
  const header = resolveElement(p.listHeaderComponent);
453
452
  if (header !== undefined) {
454
- children.push(h('symbiote-view', { key: 'list-header' }, [header]));
453
+ children.push(h('view', { key: 'list-header' }, [header]));
455
454
  }
456
455
  let renderedStickyIndices = [];
457
456
  if (m.count === FIRST_INDEX) {
458
457
  const empty = resolveElement(p.listEmptyComponent);
459
458
  if (empty !== undefined) {
460
- children.push(h('symbiote-view', { key: 'list-empty' }, [empty]));
459
+ children.push(h('view', { key: 'list-empty' }, [empty]));
461
460
  }
462
461
  }
463
462
  else {
@@ -474,7 +473,7 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
474
473
  });
475
474
  renderedStickyIndices = plan.stickyChildPositions;
476
475
  if (plan.leadingExtent > EMPTY_OFFSET) {
477
- children.push(h('symbiote-view', {
476
+ children.push(h('view', {
478
477
  key: 'spacer-leading',
479
478
  style: p.horizontal
480
479
  ? { width: plan.leadingExtent }
@@ -512,7 +511,7 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
512
511
  cell.index < m.count - 1
513
512
  ? renderSeparatorElement(p.itemSeparatorComponent, item, p.getItem(p.data, cell.index + 1), separatorOverrides.get(cell.index))
514
513
  : undefined;
515
- children.push(h('symbiote-view', {
514
+ children.push(h('view', {
516
515
  key: `cell-${cell.key}`,
517
516
  onLayout: makeCellMeasure(cell.index),
518
517
  style: cellInverted,
@@ -524,7 +523,7 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
524
523
  if (plan.forcedStickyCell !== undefined) {
525
524
  pushCell(plan.forcedStickyCell);
526
525
  if (plan.gapExtent > EMPTY_OFFSET) {
527
- children.push(h('symbiote-view', {
526
+ children.push(h('view', {
528
527
  key: 'spacer-gap',
529
528
  style: p.horizontal
530
529
  ? { width: plan.gapExtent }
@@ -536,7 +535,7 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
536
535
  pushCell(plan.cells[cellPos]);
537
536
  }
538
537
  if (plan.trailingExtent > EMPTY_OFFSET) {
539
- children.push(h('symbiote-view', {
538
+ children.push(h('view', {
540
539
  key: 'spacer-trailing',
541
540
  style: p.horizontal
542
541
  ? { width: plan.trailingExtent }
@@ -546,7 +545,7 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
546
545
  }
547
546
  const footer = resolveElement(p.listFooterComponent);
548
547
  if (footer !== undefined) {
549
- children.push(h('symbiote-view', { key: 'list-footer' }, [footer]));
548
+ children.push(h('view', { key: 'list-footer' }, [footer]));
550
549
  }
551
550
  const resolvedContentContainerStyle = p.horizontal
552
551
  ? [p.contentContainerStyle, { width: m.total }]
@@ -554,14 +553,15 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
554
553
  const resolvedStyle = p.inverted
555
554
  ? [p.style, p.horizontal ? INVERTED_X_STYLE : INVERTED_Y_STYLE]
556
555
  : p.style;
556
+ // `horizontal` is NOT in the bag: the axis is the TAG (`horizontal-scroll-view`), so passing
557
+ // it would be redundant at best and a contradiction the behavior has to warn about at worst.
557
558
  const scrollProps = {
558
559
  ...p.forwarded,
559
560
  style: resolvedStyle,
560
561
  contentContainerStyle: resolvedContentContainerStyle,
561
- horizontal: p.horizontal,
562
562
  onScroll,
563
563
  onLayout: onViewportLayout,
564
- ref: setScrollHandle,
564
+ ref: setScrollNodeRef,
565
565
  };
566
566
  // The raw scroll-lifecycle callbacks (onScrollBeginDrag/…) and scrollEventThrottle are NOT in
567
567
  // PROP_KEYS, so they already ride through via ...p.forwarded. The keyboard props come from
@@ -588,18 +588,23 @@ export const VirtualizedList = defineComponent((props, { attrs, expose, emit, sl
588
588
  (header !== undefined ? 1 : 0),
589
589
  };
590
590
  }
591
- // Pull-to-refresh: when a @refresh listener is present, build a RefreshControl for the
592
- // ScrollView's refreshControl prop (iOS sibling / Android wrap, owned by ScrollView). The
591
+ // Pull-to-refresh: when a @refresh listener is present, the RefreshControl is an ordinary
592
+ // FIRST CHILD on both platforms rather than a prop — the scroll behavior CLAIMS it, so the
593
+ // engine keeps it beside the content view on iOS and inverts the tree on Android. The
593
594
  // onRefresh bridge is gated on the listener, so an unlistened list builds no control.
595
+ let refreshControl;
594
596
  if (p.onRefresh !== undefined) {
595
597
  dlog('Vue VirtualizedList wiring RefreshControl (@refresh listened)');
596
- scrollProps.refreshControl = h(RefreshControl, {
598
+ refreshControl = h('refresh-control', {
597
599
  refreshing: p.refreshing,
598
600
  onRefresh: p.onRefresh,
599
601
  progressViewOffset: p.progressViewOffset,
600
602
  });
601
603
  }
602
- return h(ScrollView, scrollProps, { default: () => children });
604
+ // The scroll TAG, not a wrapper: the engine builds the content node, carries
605
+ // `contentContainerStyle` onto it and places the refresh control. `ref` hands back the
606
+ // engine node, which is what `buildScrollViewHandle` drives for the imperative scrolls.
607
+ return h(p.horizontal ? 'horizontal-scroll-view' : 'scroll-view', scrollProps, refreshControl === undefined ? children : [refreshControl, ...children]);
603
608
  };
604
609
  }, {
605
610
  name: 'VirtualizedList',
@@ -68,21 +68,21 @@ export type IVirtualizedSectionListEmits = {
68
68
  refresh: () => void;
69
69
  };
70
70
  export declare const VirtualizedSectionList: new <ItemT>(props: (IVirtualizedSectionListProps<ItemT> & ({} | {
71
- onRefresh?: (() => any) | undefined;
72
71
  onEndReached?: ((info: {
73
72
  distanceFromEnd: number;
74
73
  }) => any) | undefined;
75
74
  onStartReached?: ((info: {
76
75
  distanceFromStart: number;
77
76
  }) => any) | undefined;
78
- })) & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps) => import("vue").CreateComponentPublicInstanceWithMixins<IVirtualizedSectionListProps<ItemT> & ({} | {
79
77
  onRefresh?: (() => any) | undefined;
78
+ })) & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps) => import("vue").CreateComponentPublicInstanceWithMixins<IVirtualizedSectionListProps<ItemT> & ({} | {
80
79
  onEndReached?: ((info: {
81
80
  distanceFromEnd: number;
82
81
  }) => any) | undefined;
83
82
  onStartReached?: ((info: {
84
83
  distanceFromStart: number;
85
84
  }) => any) | undefined;
85
+ onRefresh?: (() => any) | undefined;
86
86
  }), {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} | IVirtualizedSectionListEmits, import("vue").PublicProps, {}, false, {}, import("vue").SlotsType<IVirtualizedSectionListSlots<ItemT>>, {}, {}, string, {}, any, import("vue").ComponentProvideOptions, {
87
87
  P: {};
88
88
  B: {};
@@ -91,11 +91,11 @@ export declare const VirtualizedSectionList: new <ItemT>(props: (IVirtualizedSec
91
91
  M: {};
92
92
  Defaults: {};
93
93
  }, (IVirtualizedSectionListProps<ItemT> & {}) | (IVirtualizedSectionListProps<ItemT> & {
94
- onRefresh?: (() => any) | undefined;
95
94
  onEndReached?: ((info: {
96
95
  distanceFromEnd: number;
97
96
  }) => any) | undefined;
98
97
  onStartReached?: ((info: {
99
98
  distanceFromStart: number;
100
99
  }) => any) | undefined;
100
+ onRefresh?: (() => any) | undefined;
101
101
  }), {}, {}, {}, {}, {}>;
@@ -0,0 +1 @@
1
+ export declare function useRawAttrs(contextAttrs: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,26 @@
1
+ // The unproxied twin of a setup context's `attrs`.
2
+ //
3
+ // Vue hands `setupContext.attrs` out as `new Proxy(instance.attrs, attrsProxyHandlers)`, and in
4
+ // PRODUCTION as well as dev that proxy's only trap is `get(target, key) { track(target, "get", "");
5
+ // return target[key]; }` (runtime-core.esm-bundler.js:8357). So every attribute read costs a
6
+ // WeakMap get, a Map get and a `dep.track()`, and the first read of each instance also allocates
7
+ // a Map and a Dep into the module-global `targetMap` that live as long as the component does.
8
+ // Pressable reads ~16 attrs per render and a benchmark create mounts 2 000 of them.
9
+ //
10
+ // `instance.attrs` is the raw object behind that proxy. Capturing it is safe because its identity
11
+ // never changes: `initProps` assigns it once (:4907) and `updateProps` mutates that same object in
12
+ // place (`attrs[key] = value` / `delete attrs[key]`), so a reference taken at setup always reads
13
+ // current values. The tracking the proxy performs is for reads in a setup BODY; a render fn does
14
+ // not need it, because the parent's patch re-runs the child render through `updateComponentPreRender`
15
+ // whether or not the child subscribed.
16
+ //
17
+ // CALL THIS FROM A SETUP BODY ONLY, never from a render fn, a `computed`, or any other deferred
18
+ // callback. `getCurrentInstance()` resolves to `currentInstance || currentRenderingInstance`, so in
19
+ // a callback that runs while a DIFFERENT component is rendering it returns that component and this
20
+ // would silently hand back the wrong bag. `virtualized-list/index.ts` calls normalizeVueAttrs
21
+ // inside a `computed` for exactly that reason and must keep using the context attrs.
22
+ import { getCurrentInstance } from '@vue/runtime-core';
23
+ export function useRawAttrs(contextAttrs) {
24
+ const instance = getCurrentInstance();
25
+ return instance === null ? contextAttrs : instance.attrs;
26
+ }
@@ -1,7 +1,7 @@
1
1
  // The descriptor→element bridge for Vue. A render function in @symbiote-native/components returns
2
2
  // a framework-agnostic `Descriptor` tree; this maps it onto Vue vnodes via h(). The host
3
- // vnode (`symbiote-view`, `symbiote-activity-indicator`, …) flows on through the Vue custom
4
- // renderer → engine → Fabric, exactly like a hand-written h('symbiote-view'). The React
3
+ // vnode (`view`, `activity-indicator`, …) flows on through the Vue custom
4
+ // renderer → engine → Fabric, exactly like a hand-written h('view'). The React
5
5
  // twin is `adapters/react/src/descriptor-to-react.ts`.
6
6
  import { h } from '@vue/runtime-core';
7
7
  export function descriptorToVue(node) {
@@ -1,11 +1,10 @@
1
1
  // findNodeHandle, the Vue adapter twin of adapters/react/src/host-instance.ts. RN's
2
2
  // "ref/instance -> native reactTag" lookup, the seam imperative-interop libraries
3
3
  // (reanimated, gesture-handler, react-navigation) reach through. A Vue template/function ref
4
- // to a symbiote host element falls through to the raw engine SymbioteNode, and the Vue
5
- // renderer grafts the public-instance API onto it (toPublicInstance in renderer.ts), so the
6
- // node a ref receives carries measure / setNativeProps / focus exactly like React's
7
- // getPublicInstance. IHostInstance is therefore that grafted node — re-exported from the
8
- // engine so React and Vue share one definition.
4
+ // to a symbiote host element falls through to the raw engine SymbioteNode, which already carries
5
+ // measure / setNativeProps / focus on its prototype, exactly like React's getPublicInstance.
6
+ // IHostInstance is therefore that node — re-exported from the engine so React and Vue share one
7
+ // definition.
9
8
  //
10
9
  // The node -> tag resolution itself belongs to the engine (getNativeTag, keyed on the raw
11
10
  // node in the commit mirror); this only unwraps the Vue-shaped inputs (a Ref or a bare node)
package/build/index.d.ts CHANGED
@@ -1,29 +1,31 @@
1
+ import './register';
2
+ export * from 'vue';
1
3
  export { mount, unmount, setAppConfigurator } from './render';
2
4
  export type { IAppConfigurator } from './render';
3
5
  export { Teleport, type ITeleportTarget } from './create-portal';
4
6
  export { createTunnel, type ITunnel } from './create-tunnel';
5
- export { View, Text } from './components';
7
+ export type { IViewProps } from './components/view-props';
8
+ export type { ITextProps } from './components/text-props';
9
+ export type { ISymbioteIntrinsicTag, ISymbioteHostAttributes, } from './intrinsic-elements';
6
10
  export type { IAccessibilityProps, IAriaProps, IAccessibilityRole, IRole, IAccessibilityStateValue, IAccessibilityValue, IAccessibilityActionInfo, IResponderProps, } from '@symbiote-native/components';
7
11
  export { findNodeHandle } from './host-instance';
8
12
  export type { IHostInstance } from './host-instance';
9
- export { Image, setImageSourceResolver } from './components/image';
10
- export type { IImageProps, IImageSource, IImageSourceProp, IResizeMode, IImageSize, IImageCacheStatus, } from './components/image';
11
- export { ActivityIndicator } from './components/activity-indicator';
12
- export type { IActivityIndicatorProps } from './components/activity-indicator';
13
- export { Switch } from './components/switch';
14
- export type { ISwitchProps, ISwitchTrackColor } from './components/switch';
15
- export { ScrollView } from './components/scroll-view';
16
- export type { IScrollViewProps, IScrollViewEmits, IScrollViewHandle, } from './components/scroll-view';
17
- export { Pressable } from './components/pressable';
18
- export type { IPressableProps, IPressableSlots, IPressState, IPressableAndroidRippleConfig, } from './components/pressable';
19
- export { TouchableOpacity, TouchableHighlight, TouchableWithoutFeedback, } from './components/touchable';
20
- export type { ITouchableOpacityProps, ITouchableHighlightProps, ITouchableWithoutFeedbackProps, } from './components/touchable';
21
- export { TouchableNativeFeedback } from './components/touchable-native-feedback';
22
- export type { INativeFeedbackBackground, IThemeAttrBackground, IRippleBackground, ITouchableNativeFeedbackProps, } from './components/touchable-native-feedback';
23
- export { Button } from './components/button';
24
- export type { IButtonProps } from './components/button';
25
- export { TextInput } from './components/text-input';
26
- export type { ITextInputProps, ITextInputHandle, } from './components/text-input';
13
+ export { Image } from './modules/image';
14
+ export { setImageSourceResolver } from '@symbiote-native/components';
15
+ export type { IImageProps } from './components/image-props';
16
+ export type { IImageSource, IImageSourceProp, IResizeMode, IImageSize, IImageCacheStatus, } from '@symbiote-native/components';
17
+ export type { IActivityIndicatorProps } from './components/activity-indicator-props';
18
+ export type { ISwitchProps, ISwitchTrackColor, ISwitchChangeEvent, } from './components/switch/switch-props';
19
+ export type { IScrollViewProps, IScrollViewHandle, } from './components/scroll-view/scroll-view-props';
20
+ export type { IPressableProps, IPressState, IPressableAndroidRippleConfig, } from './components/pressable-props';
21
+ export type { ITouchableOpacityProps, ITouchableHighlightProps, } from './components/touchable-props';
22
+ export type { ITouchableWithoutFeedbackProps } from './components/touchable-without-feedback-props';
23
+ export { TouchableNativeFeedback } from '@symbiote-native/components';
24
+ export type { INativeFeedbackBackground, IThemeAttrBackground, IRippleBackground, } from '@symbiote-native/components';
25
+ export type { ITouchableNativeFeedbackProps } from './components/touchable-native-feedback-props';
26
+ export type { IButtonProps } from './components/button-props';
27
+ export type { ITextInputProps } from './components/text-input/text-input-props';
28
+ export type { ITextInputHandle, ITextInputChangeEvent, } from '@symbiote-native/components';
27
29
  export { VirtualizedList } from './components/virtualized-list';
28
30
  export type { IVirtualizedListProps, IVirtualizedListSlots, IVirtualizedListEmits, IVirtualizedListHandle, ISeparators, ISeparatorProps, IViewToken, IViewableItemsChangedInfo, IViewabilityConfig, IViewabilityConfigCallbackPair, ICellLayout, } from './components/virtualized-list';
29
31
  export { FlatList } from './components/flat-list';
@@ -32,19 +34,15 @@ export { VirtualizedSectionList } from './components/virtualized-section-list';
32
34
  export type { IVirtualizedSectionListProps, IVirtualizedSectionListSlots, IVirtualizedSectionListEmits, IVirtualizedSectionListHandle, } from './components/virtualized-section-list';
33
35
  export { SectionList } from './components/section-list';
34
36
  export type { ISection, ISectionListProps, ISectionListSlots, ISectionListEmits, ISectionListHandle, } from './components/section-list';
35
- export { SafeAreaView } from './components/safe-area-view';
36
- export type { ISafeAreaViewProps } from './components/safe-area-view';
37
- export { RefreshControl } from './components/refresh-control';
38
- export type { IRefreshControlProps, IRefreshControlEmits, } from './components/refresh-control';
37
+ export type { ISafeAreaViewProps } from './components/safe-area-view-props';
38
+ export type { IRefreshControlProps } from './components/refresh-control-props';
39
39
  export { descriptorToVue } from './descriptor-to-vue';
40
40
  export { normalizeVueAttrs } from './utils/normalize-attrs';
41
41
  export { resolveModelValue, emitModelUpdate } from './utils/model-binding';
42
42
  export { createSymbioteRenderer } from './renderer';
43
43
  export { Animated, createAnimatedComponent } from './modules/animated';
44
- export { ImageBackground } from './components/image-background';
45
- export type { IImageBackgroundProps } from './components/image-background';
46
- export { InputAccessoryView } from './components/input-accessory-view';
47
- export type { IInputAccessoryViewProps } from './components/input-accessory-view';
44
+ export type { IImageBackgroundProps } from './components/image-background-props';
45
+ export type { IInputAccessoryViewProps } from './components/input-accessory-view-props';
48
46
  export { Modal } from './components/modal';
49
47
  export type { IModalProps, IModalEmits, IModalAnimationType, IModalPresentationStyle, IModalOrientation, IModalOrientationChangeEvent, } from './components/modal';
50
48
  export { KeyboardAvoidingView } from './components/keyboard-avoiding-view';
package/build/index.js CHANGED
@@ -1,6 +1,32 @@
1
1
  // @symbiote-native/vue: a thin Vue 3 reconciler over @symbiote-native/engine. createRenderer maps
2
2
  // each RendererOptions call onto the engine's mutation API; all Fabric clone-on-write
3
3
  // lives in the engine, shared with every other adapter. App code names only @symbiote-native/vue.
4
+ // Side-effect import, FIRST and deliberately not a re-export: it installs the engine-side press
5
+ // machine that a lowered `<pressable>` needs. `export * from './register'` or a bare
6
+ // import sitting beside a re-export of the same specifier both go lazy under Metro's production
7
+ // `inlineRequires` and the registration silently never runs in a release build. See register.ts.
8
+ import './register.js';
9
+ // Re-exports Vue's ENTIRE public API (ref, computed, defineComponent, unref, …), which looks like
10
+ // scope creep on an otherwise carefully curated barrel — it is not ergonomics, it is what makes
11
+ // `vueCompilerOptions.lib: "@symbiote-native/vue"` (examples/*/tsconfig.typecheck.json) safe to
12
+ // set. Volar/`@vue/language-core` generates virtual TS referencing `import(lib).unref`,
13
+ // `import(lib).GlobalComponents`, `.GlobalDirectives`, `.ShallowRef`, `.ObjectDirective` — always
14
+ // off `lib`'s ROOT import, never a subpath — so pointing `lib` at us without this line breaks
15
+ // EVERY `.vue` SFC's template check with `Cannot find name` the moment Volar's codegen touches any
16
+ // of them. `lib`'s other consumer, `optionsWrapper`'s `(await import(lib)).defineComponent(...)`,
17
+ // only fires for a plain `<script>` `export default {}` block (`isExportRawObject`,
18
+ // `@vue/language-core/lib/codegen/script/index.js`) — every `.vue` file in this repo uses
19
+ // `<script setup>`, so that branch never runs and defineComponent needing to resolve from here too
20
+ // is moot in practice, not something this wildcard has to get right on its own.
21
+ //
22
+ // WHY `lib` NEEDS TO BE US AT ALL: plain `"vue"` (Volar's default) types `__VLS_IntrinsicElements`
23
+ // and `GlobalComponents` off `vue`'s own `jsx-runtime`/ambient augmentation — the SAME
24
+ // `view`/`text`/`image`/`switch`-collide-with-real-SVG-elements problem documented in
25
+ // `jsx-runtime.ts` and `intrinsic-elements.ts`, but for `.vue` TEMPLATES rather than TSX. Volar's
26
+ // native-vs-component branch (`!isNativeTag(tag)`) reads `IntrinsicElements` from
27
+ // `import('${lib}/jsx-runtime')`, so redirecting `lib` to our own package is what finally reaches
28
+ // OUR jsx-runtime.ts (real `IViewProps`/`ITextProps`/… on all 4 collision tags) for those four.
29
+ export * from 'vue';
4
30
  export { mount, unmount, setAppConfigurator } from './render.js';
5
31
  // The portal: Vue's own <Teleport>, guarded so `to` must be a node/surface this renderer actually
6
32
  // mounted (there is no querySelector). It MOVES host nodes, so it reaches any already-mounted
@@ -10,26 +36,22 @@ export { mount, unmount, setAppConfigurator } from './render.js';
10
36
  // into an <Out/> the destination has to render. See create-portal/index.ts.
11
37
  export { Teleport } from './create-portal/index.js';
12
38
  export { createTunnel } from './create-tunnel/index.js';
13
- export { View, Text } from './components.js';
14
39
  // IHostInstance is the raw engine node (Vue host refs fall through to it; imperative methods
15
40
  // live on each component's expose() handle).
16
41
  export { findNodeHandle } from './host-instance/index.js';
17
- export { Image, setImageSourceResolver } from './components/image.js';
18
- export { ActivityIndicator } from './components/activity-indicator';
19
- export { Switch } from './components/switch';
20
- export { ScrollView } from './components/scroll-view';
21
- export { Pressable } from './components/pressable.js';
22
- export { TouchableOpacity, TouchableHighlight, TouchableWithoutFeedback, } from './components/touchable.js';
23
- export { TouchableNativeFeedback } from './components/touchable-native-feedback.js';
24
- export { Button } from './components/button.js';
25
- export { TextInput } from './components/text-input/index.js';
42
+ // `Image` is a TAG — `<image>`. What survives the name is the STATICS namespace, and it lives in
43
+ // `modules/` beside Alert/Share because it carries no view; the prop type stays, for a component
44
+ // forwarding a bag.
45
+ export { Image } from './modules/image/index.js';
46
+ export { setImageSourceResolver } from '@symbiote-native/components';
47
+ // `TouchableNativeFeedback` is now RN's STATIC NAMESPACE, not a component: the element is the tag
48
+ // `<touchable-native-feedback>`, which commits no node of its own and clones onto its single child.
49
+ // `TouchableNativeFeedback.Ripple(…)` / `.SelectableBackground(…)` are unchanged.
50
+ export { TouchableNativeFeedback } from '@symbiote-native/components';
26
51
  export { VirtualizedList } from './components/virtualized-list/index.js';
27
52
  export { FlatList } from './components/flat-list/index.js';
28
53
  export { VirtualizedSectionList } from './components/virtualized-section-list/index.js';
29
54
  export { SectionList } from './components/section-list/index.js';
30
- // RefreshControl hosts the wrapped scroll view via its default slot.
31
- export { SafeAreaView } from './components/safe-area-view.js';
32
- export { RefreshControl } from './components/refresh-control.js';
33
55
  export { descriptorToVue } from './descriptor-to-vue.js';
34
56
  // Exported so an external wrapper package (e.g. @symbiote-native/slider/vue over a third-party
35
57
  // native view) can fold its incoming attrs/v-model through the SAME transform rather than
@@ -38,8 +60,6 @@ export { normalizeVueAttrs } from './utils/normalize-attrs.js';
38
60
  export { resolveModelValue, emitModelUpdate } from './utils/model-binding.js';
39
61
  export { createSymbioteRenderer } from './renderer/index.js';
40
62
  export { Animated, createAnimatedComponent } from './modules/animated/index.js';
41
- export { ImageBackground } from './components/image-background.js';
42
- export { InputAccessoryView } from './components/input-accessory-view.js';
43
63
  export { Modal } from './components/modal/index.js';
44
64
  export { KeyboardAvoidingView } from './components/keyboard-avoiding-view.js';
45
65
  export { StatusBar } from './modules/status-bar.js';
@@ -0,0 +1,19 @@
1
+ import type { PublicProps } from '@vue/runtime-core';
2
+ import type { ISymbioteIntrinsic, ICrossTypedIntrinsics } from '@symbiote-native/components';
3
+ import type { ICrossedPrimitiveProps } from './jsx-runtime';
4
+ export interface ISymbioteHostAttributes {
5
+ [attribute: string]: unknown;
6
+ }
7
+ type IDefineIntrinsic<Props> = new () => {
8
+ /** @deprecated Template prop types only — this property does not exist at runtime. */
9
+ $props: Props & PublicProps;
10
+ };
11
+ type IDefineIntrinsicMap<M> = {
12
+ [K in keyof M]: IDefineIntrinsic<M[K]>;
13
+ };
14
+ declare module 'vue' {
15
+ interface GlobalComponents extends ICrossTypedIntrinsics<IDefineIntrinsic<ISymbioteHostAttributes>, IDefineIntrinsicMap<ICrossedPrimitiveProps>> {
16
+ }
17
+ }
18
+ export type ISymbioteIntrinsicTag = ISymbioteIntrinsic;
19
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,67 @@
1
+ import type { VNode } from '@vue/runtime-core';
2
+ import type { ICrossTypedIntrinsics } from '@symbiote-native/components';
3
+ import type { IViewProps } from './components/view-props';
4
+ import type { ITextProps } from './components/text-props';
5
+ import type { IPressableProps } from './components/pressable-props';
6
+ import type { IButtonProps } from './components/button-props';
7
+ import type { IImageProps } from './components/image-props';
8
+ import type { IImageBackgroundProps } from './components/image-background-props';
9
+ import type { IInputAccessoryViewProps } from './components/input-accessory-view-props';
10
+ import type { IRefreshControlProps } from './components/refresh-control-props';
11
+ import type { ISafeAreaViewProps } from './components/safe-area-view-props';
12
+ import type { ITouchableNativeFeedbackProps } from './components/touchable-native-feedback-props';
13
+ import type { ITouchableOpacityProps, ITouchableHighlightProps } from './components/touchable-props';
14
+ import type { ITouchableWithoutFeedbackProps } from './components/touchable-without-feedback-props';
15
+ import type { IScrollViewProps } from './components/scroll-view/scroll-view-props';
16
+ import type { ISwitchProps } from './components/switch/switch-props';
17
+ import type { ITextInputProps } from './components/text-input/text-input-props';
18
+ import type { IModalProps } from './components/modal';
19
+ import type { IActivityIndicatorProps } from './components/activity-indicator-props';
20
+ export {};
21
+ export interface ICrossedPrimitiveProps {
22
+ view: IViewProps;
23
+ text: ITextProps;
24
+ pressable: IPressableProps;
25
+ button: IButtonProps;
26
+ image: IImageProps;
27
+ 'image-background': IImageBackgroundProps;
28
+ 'input-accessory-view': IInputAccessoryViewProps;
29
+ 'refresh-control': IRefreshControlProps;
30
+ 'safe-area-view': ISafeAreaViewProps;
31
+ 'touchable-native-feedback': ITouchableNativeFeedbackProps;
32
+ 'touchable-opacity': ITouchableOpacityProps;
33
+ 'touchable-highlight': ITouchableHighlightProps;
34
+ 'touchable-without-feedback': ITouchableWithoutFeedbackProps;
35
+ 'scroll-view': IScrollViewProps;
36
+ switch: ISwitchProps;
37
+ 'text-input': ITextInputProps;
38
+ modal: IModalProps;
39
+ 'activity-indicator': IActivityIndicatorProps;
40
+ }
41
+ interface IHostAttributes {
42
+ [attribute: string]: unknown;
43
+ }
44
+ export declare namespace JSX {
45
+ export interface Element extends VNode {
46
+ }
47
+ export interface ElementClass {
48
+ $props: {};
49
+ }
50
+ export interface ElementAttributesProperty {
51
+ $props: {};
52
+ }
53
+ export interface IntrinsicAttributes {
54
+ key?: string | number | symbol;
55
+ [name: string]: unknown;
56
+ }
57
+ type IWithJsxAttrs<Props> = Props & {
58
+ key?: string | number | symbol;
59
+ ref?: import('@vue/runtime-core').VNodeRef;
60
+ };
61
+ export interface IntrinsicElements extends ICrossTypedIntrinsics<IHostAttributes, {
62
+ [K in keyof ICrossedPrimitiveProps]: IWithJsxAttrs<ICrossedPrimitiveProps[K]>;
63
+ }> {
64
+ }
65
+ export {};
66
+ }
67
+ export type ISymbioteIntrinsicTag = keyof JSX.IntrinsicElements;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
1
  import { type Component } from '@vue/runtime-core';
2
- export declare function createAnimatedComponent(Component: Component): import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
2
+ export declare function createAnimatedComponent(Component: Component | string): import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
3
3
  [key: string]: any;
4
4
  }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;