@symbiote-native/react 1.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -14
- package/build/components/activity-indicator-props.d.ts +4 -0
- package/build/components/{button.d.ts → button-props.d.ts} +0 -2
- package/build/components/button-props.js +1 -0
- package/build/components/flat-list/index.js +3 -3
- package/build/components/image/image-props.d.ts +4 -0
- package/build/components/image/image-props.js +1 -0
- package/build/components/image-background-props.d.ts +9 -0
- package/build/components/image-background-props.js +1 -0
- package/build/components/input-accessory-view-props.d.ts +10 -0
- package/build/components/input-accessory-view-props.js +1 -0
- package/build/components/keyboard-avoiding-view/index.js +10 -5
- package/build/components/modal/index.js +3 -3
- package/build/components/pressable/{index.d.ts → pressable-props.d.ts} +6 -5
- package/build/components/pressable/pressable-props.js +1 -0
- package/build/components/{refresh-control/index.d.ts → refresh-control-props.d.ts} +3 -3
- package/build/components/refresh-control-props.js +1 -0
- package/build/components/safe-area-view-props.d.ts +11 -0
- package/build/components/safe-area-view-props.js +1 -0
- package/build/components/scroll-view/{shared.d.ts → scroll-view-props.d.ts} +4 -26
- package/build/components/scroll-view/scroll-view-props.js +1 -0
- package/build/components/switch/switch-props.d.ts +4 -0
- package/build/components/switch/switch-props.js +1 -0
- package/build/components/text-input/text-input-props.d.ts +4 -0
- package/build/components/text-input/text-input-props.js +1 -0
- package/build/components/touchable/touchable-props.d.ts +19 -0
- package/build/components/touchable/touchable-props.js +1 -0
- package/build/components/touchable-native-feedback/touchable-native-feedback-props.d.ts +9 -0
- package/build/components/touchable-native-feedback/touchable-native-feedback-props.js +1 -0
- package/build/components/touchable-without-feedback/touchable-without-feedback-props.d.ts +7 -0
- package/build/components/touchable-without-feedback/touchable-without-feedback-props.js +1 -0
- package/build/components/virtualized-list/index.js +90 -41
- package/build/components.d.ts +1 -2
- package/build/components.js +5 -19
- package/build/create-portal/index.js +1 -1
- package/build/create-tunnel/index.js +1 -1
- package/build/descriptor-to-react/index.js +1 -1
- package/build/host-config.js +23 -12
- package/build/index.d.ts +23 -28
- package/build/index.js +14 -14
- package/build/jsx-dev-runtime.d.ts +3 -0
- package/build/jsx-dev-runtime.js +10 -0
- package/build/jsx-namespace.type-check.d.ts +1 -0
- package/build/jsx-namespace.type-check.js +7 -0
- package/build/jsx-runtime.d.ts +62 -0
- package/build/jsx-runtime.js +1 -0
- package/build/modules/animated/index.d.ts +29 -20
- package/build/modules/animated/index.js +16 -22
- package/build/modules/image/index.d.ts +3 -0
- package/build/modules/image/index.js +14 -0
- package/build/register.d.ts +1 -0
- package/build/register.js +15 -0
- package/metro-css-parser.cjs +2 -1
- package/package.json +12 -8
- package/build/components/activity-indicator/index.android.d.ts +0 -3
- package/build/components/activity-indicator/index.android.js +0 -17
- package/build/components/activity-indicator/index.d.ts +0 -1
- package/build/components/activity-indicator/index.ios.d.ts +0 -3
- package/build/components/activity-indicator/index.ios.js +0 -16
- package/build/components/activity-indicator/index.js +0 -4
- package/build/components/activity-indicator/shared.d.ts +0 -6
- package/build/components/activity-indicator/shared.js +0 -22
- package/build/components/button.js +0 -42
- package/build/components/image/index.d.ts +0 -9
- package/build/components/image/index.js +0 -28
- package/build/components/image-background/index.d.ts +0 -10
- package/build/components/image-background/index.js +0 -46
- package/build/components/input-accessory-view/index.d.ts +0 -11
- package/build/components/input-accessory-view/index.js +0 -19
- package/build/components/pressable/index.js +0 -112
- package/build/components/refresh-control/index.js +0 -21
- package/build/components/safe-area-view/index.d.ts +0 -12
- package/build/components/safe-area-view/index.js +0 -18
- package/build/components/scroll-view/index.android.d.ts +0 -3
- package/build/components/scroll-view/index.android.js +0 -61
- package/build/components/scroll-view/index.d.ts +0 -1
- package/build/components/scroll-view/index.ios.d.ts +0 -3
- package/build/components/scroll-view/index.ios.js +0 -29
- package/build/components/scroll-view/index.js +0 -4
- package/build/components/scroll-view/shared.js +0 -240
- package/build/components/scroll-view/sticky-header.d.ts +0 -18
- package/build/components/scroll-view/sticky-header.js +0 -227
- package/build/components/switch/index.android.d.ts +0 -3
- package/build/components/switch/index.android.js +0 -18
- package/build/components/switch/index.d.ts +0 -1
- package/build/components/switch/index.ios.d.ts +0 -3
- package/build/components/switch/index.ios.js +0 -16
- package/build/components/switch/index.js +0 -6
- package/build/components/switch/shared.d.ts +0 -9
- package/build/components/switch/shared.js +0 -60
- package/build/components/text-input/index.d.ts +0 -50
- package/build/components/text-input/index.js +0 -180
- package/build/components/touchable/index.d.ts +0 -22
- package/build/components/touchable/index.js +0 -165
- package/build/components/touchable-native-feedback/index.d.ts +0 -18
- package/build/components/touchable-native-feedback/index.js +0 -32
- package/build/jsx.d.ts +0 -18
- package/build/state-style.d.ts +0 -1
- package/build/state-style.js +0 -13
- /package/build/{jsx.js → components/activity-indicator-props.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// VirtualizedList: real windowing over the
|
|
1
|
+
// VirtualizedList: real windowing over the `scroll-view` TAG. Only the cells
|
|
2
2
|
// whose computed offset falls inside the visible window (plus a leading/trailing
|
|
3
3
|
// buffer) are rendered; everything above and below is collapsed into two spacer
|
|
4
4
|
// Views whose sizes sum to the off-screen extent, so the scroll thumb and total
|
|
@@ -14,14 +14,31 @@
|
|
|
14
14
|
// from a `commit` dispatched in a layout effect (before paint, so MVCP's shift lands without a
|
|
15
15
|
// visible jump). Lists have no Descriptor render fn — the cell content is React's own children.
|
|
16
16
|
//
|
|
17
|
-
// Imperative scrolling resolves to an offset in the reducer and rides the
|
|
18
|
-
// scrollTo command
|
|
19
|
-
//
|
|
17
|
+
// Imperative scrolling resolves to an offset in the reducer and rides the scroll node's native
|
|
18
|
+
// scrollTo command, animated by default. The `contentOffset` prop is only a fallback for the
|
|
19
|
+
// pre-mount window (the node not yet attached).
|
|
20
|
+
//
|
|
21
|
+
// WHAT IS STILL THIS COMPONENT'S, now that the scroll view is a tag and the engine owns its
|
|
22
|
+
// content node, its sticky seam and its RefreshControl placement — checked rather than assumed,
|
|
23
|
+
// because "the wrapper is gone" and "nothing is left" are different claims:
|
|
24
|
+
//
|
|
25
|
+
// the WINDOW `reduceList` decides which indices are in view, and this file is what
|
|
26
|
+
// turns that into elements. The output SHAPE is decided in JS from the
|
|
27
|
+
// app's own data through `renderItem` — the one disqualifier that no
|
|
28
|
+
// engine seam removes (`.claude/rules/host-primitive-tier.md`, tier 3).
|
|
29
|
+
// the CELL WRAPPERS a measuring `view` per cell with the inversion counter-flip, the two
|
|
30
|
+
// spacers, the header/footer/empty slots, the separator INSIDE the cell.
|
|
31
|
+
// the LIFECYCLE native events -> actions, effects run with React primitives (timers, a
|
|
32
|
+
// forced re-render, a layout effect for MVCP), one state cell.
|
|
33
|
+
// the HANDLE `buildScrollViewHandle` over the node a `ref` hands back, plus the list's
|
|
34
|
+
// own imperative surface on top of it.
|
|
35
|
+
//
|
|
36
|
+
// What is NOT: the content node, `contentContainerStyle`'s routing, where a RefreshControl goes
|
|
37
|
+
// per platform, and how a sticky header pins. The list names `sticky-header` on a cell and knows
|
|
38
|
+
// nothing else about it.
|
|
20
39
|
import { createElement, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, } from 'react';
|
|
21
40
|
import { dlog, } from '@symbiote-native/engine';
|
|
22
|
-
import {
|
|
23
|
-
import { ScrollView, } from '../scroll-view';
|
|
24
|
-
import { RefreshControl } from '../refresh-control/index.js';
|
|
41
|
+
import { DEFAULT_INITIAL_NUM_TO_RENDER, DEFAULT_MAX_TO_RENDER_PER_BATCH, 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';
|
|
25
42
|
function resolveElement(component) {
|
|
26
43
|
if (component === undefined)
|
|
27
44
|
return undefined;
|
|
@@ -48,7 +65,7 @@ function renderSeparatorElement(component, leadingItem, trailingItem, overrides)
|
|
|
48
65
|
// generic). The ref is destructured here and wired through useImperativeHandle.
|
|
49
66
|
export function VirtualizedList(props) {
|
|
50
67
|
const forwardedRef = props.ref;
|
|
51
|
-
const { data, getItem, getItemCount, renderItem, keyExtractor, getItemLayout, ItemSeparatorComponent, ListHeaderComponent, ListFooterComponent, ListEmptyComponent, horizontal = false, inverted = false, extraData, onEndReached, onEndReachedThreshold
|
|
68
|
+
const { data, getItem, getItemCount, renderItem, keyExtractor, getItemLayout, ItemSeparatorComponent, ListHeaderComponent, ListFooterComponent, ListEmptyComponent, horizontal = false, inverted = false, extraData, onEndReached, onEndReachedThreshold, onStartReached, onStartReachedThreshold, onRefresh, refreshing, progressViewOffset, onViewableItemsChanged, viewabilityConfig, viewabilityConfigCallbackPairs, onScrollToIndexFailed, initialNumToRender = DEFAULT_INITIAL_NUM_TO_RENDER, initialScrollIndex, maxToRenderPerBatch = DEFAULT_MAX_TO_RENDER_PER_BATCH, updateCellsBatchingPeriod = DEFAULT_UPDATE_CELLS_BATCHING_PERIOD, windowSize = DEFAULT_WINDOW_SIZE, stickyHeaderIndices, maintainVisibleContentPosition, style, contentContainerStyle,
|
|
52
69
|
// Pulled out of the rest so the user's onScroll does NOT arrive raw via
|
|
53
70
|
// ...accessibilityRest and overwrite the internal windowing handler. Composed below.
|
|
54
71
|
onScroll: userOnScroll, onScrollBeginDrag, onScrollEndDrag, onMomentumScrollBegin, onMomentumScrollEnd, scrollEventThrottle, keyboardShouldPersistTaps, keyboardDismissMode,
|
|
@@ -101,7 +118,12 @@ export function VirtualizedList(props) {
|
|
|
101
118
|
// The offset we are imperatively driving native to (scrollTo* before the handle attaches). Pushed
|
|
102
119
|
// down as the ScrollView's contentOffset prop; fresh object identity each time. undefined = none.
|
|
103
120
|
const [commandedOffset, setCommandedOffset] = useState(undefined);
|
|
104
|
-
|
|
121
|
+
// The engine node of the scroll TAG. A `ref` on an intrinsic hands back the host instance, so
|
|
122
|
+
// there is no wrapper left to run a `useImperativeHandle` — `buildScrollViewHandle` is what turns
|
|
123
|
+
// the node into RN's scroll surface, and it is the same function every other adapter feeds from
|
|
124
|
+
// its own host-instance accessor. Lazy getter: the node is null until commit.
|
|
125
|
+
const scrollNodeRef = useRef(null);
|
|
126
|
+
const scrollHandle = useMemo(() => buildScrollViewHandle(() => scrollNodeRef.current), []);
|
|
105
127
|
// Pending minimumViewTime debounce timer / the incremental-fill timer (adapter owns the timers;
|
|
106
128
|
// the reducer only asks for a delay).
|
|
107
129
|
const viewableTimerRef = useRef(null);
|
|
@@ -117,9 +139,9 @@ export function VirtualizedList(props) {
|
|
|
117
139
|
const target = isHorizontal
|
|
118
140
|
? { x: clamped, y: EMPTY_OFFSET }
|
|
119
141
|
: { x: EMPTY_OFFSET, y: clamped };
|
|
120
|
-
if (
|
|
142
|
+
if (scrollNodeRef.current !== null) {
|
|
121
143
|
dlog(`VirtualizedList scrollTo offset=${clamped} animated=${animated} (horizontal=${isHorizontal})`);
|
|
122
|
-
|
|
144
|
+
scrollHandle.scrollTo({ x: target.x, y: target.y, animated });
|
|
123
145
|
return;
|
|
124
146
|
}
|
|
125
147
|
dlog(`VirtualizedList scrollTo offset=${clamped} pending-ref (horizontal=${isHorizontal})`);
|
|
@@ -166,8 +188,12 @@ export function VirtualizedList(props) {
|
|
|
166
188
|
const info = effect.info;
|
|
167
189
|
const map = effect.map;
|
|
168
190
|
const fire = () => {
|
|
169
|
-
for (const pair of pairs)
|
|
170
|
-
pair.onViewableItemsChanged(
|
|
191
|
+
for (const pair of pairs) {
|
|
192
|
+
pair.onViewableItemsChanged({
|
|
193
|
+
...info,
|
|
194
|
+
viewabilityConfig: pair.viewabilityConfig,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
171
197
|
dispatchRef.current({ kind: 'viewable-fired', map });
|
|
172
198
|
};
|
|
173
199
|
if (viewableTimerRef.current !== null) {
|
|
@@ -289,18 +315,20 @@ export function VirtualizedList(props) {
|
|
|
289
315
|
dispatch({ kind: 'scroll-to-end', animated: params?.animated ?? true });
|
|
290
316
|
},
|
|
291
317
|
flashScrollIndicators: () => {
|
|
292
|
-
|
|
318
|
+
scrollHandle.flashScrollIndicators?.();
|
|
293
319
|
},
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
320
|
+
// Null until the tag commits, so these keep RN's "no scroll view yet" answer rather than
|
|
321
|
+
// handing back a handle that would silently no-op.
|
|
322
|
+
getNativeScrollRef: () => scrollNodeRef.current !== null ? scrollHandle : null,
|
|
323
|
+
getScrollableNode: () => scrollNodeRef.current !== null ? scrollHandle : null,
|
|
324
|
+
getScrollResponder: () => scrollNodeRef.current !== null ? scrollHandle : null,
|
|
325
|
+
getScrollNode: () => scrollNodeRef.current,
|
|
298
326
|
// Manual trigger for RN's recordInteraction: flip the interaction flag so
|
|
299
327
|
// waitForInteraction viewability configs start reporting.
|
|
300
328
|
recordInteraction: () => {
|
|
301
329
|
dispatch({ kind: 'record-interaction' });
|
|
302
330
|
},
|
|
303
|
-
}), [dispatch]);
|
|
331
|
+
}), [dispatch, scrollHandle]);
|
|
304
332
|
// After-commit pass: run the deferred effects (batch fill, edge-reached, viewability,
|
|
305
333
|
// initial-scroll, MVCP) in a LAYOUT effect so MVCP's shift lands before paint. Re-runs only when
|
|
306
334
|
// the windowing signature changed — the same dedup key every adapter shares.
|
|
@@ -328,15 +356,14 @@ export function VirtualizedList(props) {
|
|
|
328
356
|
const stickySet = stickyHeaderIndices !== undefined
|
|
329
357
|
? new Set(stickyHeaderIndices)
|
|
330
358
|
: undefined;
|
|
331
|
-
let renderedStickyIndices = [];
|
|
332
359
|
const header = resolveElement(ListHeaderComponent);
|
|
333
360
|
if (header !== undefined) {
|
|
334
|
-
children.push(createElement('
|
|
361
|
+
children.push(createElement('view', { key: 'list-header' }, header));
|
|
335
362
|
}
|
|
336
363
|
if (count === FIRST_INDEX) {
|
|
337
364
|
const empty = resolveElement(ListEmptyComponent);
|
|
338
365
|
if (empty !== undefined) {
|
|
339
|
-
children.push(createElement('
|
|
366
|
+
children.push(createElement('view', { key: 'list-empty' }, empty));
|
|
340
367
|
}
|
|
341
368
|
}
|
|
342
369
|
else {
|
|
@@ -352,9 +379,14 @@ export function VirtualizedList(props) {
|
|
|
352
379
|
stickyIndices: stickySet,
|
|
353
380
|
hasHeader: header !== undefined,
|
|
354
381
|
});
|
|
355
|
-
|
|
382
|
+
// `plan.stickyChildPositions` is deliberately NOT read. It was the input to the wrapper's own
|
|
383
|
+
// JS sticky pass, and the behavior honours `stickyHeaderIndices` by numbering the OWNER's paint
|
|
384
|
+
// children — which a windowed list cannot supply: it paints a header, a spacer and a slice, so
|
|
385
|
+
// data index 3 is almost never paint child 3, and the positions would have to be recomputed
|
|
386
|
+
// every time the window slides. The cells that should pin carry the `sticky-header` TAG
|
|
387
|
+
// instead, which pins by document order and survives windowing.
|
|
356
388
|
if (plan.leadingExtent > EMPTY_OFFSET) {
|
|
357
|
-
children.push(createElement('
|
|
389
|
+
children.push(createElement('view', {
|
|
358
390
|
key: 'spacer-leading',
|
|
359
391
|
style: horizontal
|
|
360
392
|
? { width: plan.leadingExtent }
|
|
@@ -374,7 +406,11 @@ export function VirtualizedList(props) {
|
|
|
374
406
|
index: forcedIndex,
|
|
375
407
|
separators: makeSeparators(forcedIndex),
|
|
376
408
|
});
|
|
377
|
-
children.push(createElement(
|
|
409
|
+
children.push(createElement(
|
|
410
|
+
// Sticky by construction — `forcedStickyCell` exists only for an index in `stickySet` —
|
|
411
|
+
// and the SAME tag the in-window branch below uses, so a cell crossing between the two
|
|
412
|
+
// keeps its element type as well as its key and never remounts.
|
|
413
|
+
'sticky-header', {
|
|
378
414
|
key: `cell-${plan.forcedStickyCell.key}`,
|
|
379
415
|
onLayout: makeCellMeasure(forcedIndex),
|
|
380
416
|
style: inverted
|
|
@@ -385,7 +421,7 @@ export function VirtualizedList(props) {
|
|
|
385
421
|
}, forcedCell));
|
|
386
422
|
}
|
|
387
423
|
if (plan.gapExtent > EMPTY_OFFSET) {
|
|
388
|
-
children.push(createElement('
|
|
424
|
+
children.push(createElement('view', {
|
|
389
425
|
key: 'spacer-gap',
|
|
390
426
|
style: horizontal
|
|
391
427
|
? { width: plan.gapExtent }
|
|
@@ -420,7 +456,13 @@ export function VirtualizedList(props) {
|
|
|
420
456
|
: undefined;
|
|
421
457
|
// Wrap each cell in a measuring View. When inverted, each cell carries the counter-flip so
|
|
422
458
|
// its content reads upright inside the flipped content container.
|
|
423
|
-
|
|
459
|
+
//
|
|
460
|
+
// A cell the app flagged sticky is wrapped in the `sticky-header` TAG instead — same
|
|
461
|
+
// position, same key, same `onLayout` (the behavior forwards it rather than replacing it),
|
|
462
|
+
// and the engine finds this scroll view by walking up. Nothing here computes a child index:
|
|
463
|
+
// the collision point comes from the owner's DOCUMENT order, which is the one form that
|
|
464
|
+
// survives windowing.
|
|
465
|
+
children.push(createElement(stickySet?.has(planCell.index) === true ? 'sticky-header' : 'view', {
|
|
424
466
|
key: `cell-${planCell.key}`,
|
|
425
467
|
onLayout: makeCellMeasure(planCell.index),
|
|
426
468
|
style: inverted
|
|
@@ -431,7 +473,7 @@ export function VirtualizedList(props) {
|
|
|
431
473
|
}, cell, separator));
|
|
432
474
|
}
|
|
433
475
|
if (plan.trailingExtent > EMPTY_OFFSET) {
|
|
434
|
-
children.push(createElement('
|
|
476
|
+
children.push(createElement('view', {
|
|
435
477
|
key: 'spacer-trailing',
|
|
436
478
|
style: horizontal
|
|
437
479
|
? { width: plan.trailingExtent }
|
|
@@ -441,7 +483,7 @@ export function VirtualizedList(props) {
|
|
|
441
483
|
}
|
|
442
484
|
const footer = resolveElement(ListFooterComponent);
|
|
443
485
|
if (footer !== undefined) {
|
|
444
|
-
children.push(createElement('
|
|
486
|
+
children.push(createElement('view', { key: 'list-footer' }, footer));
|
|
445
487
|
}
|
|
446
488
|
// A horizontal list pins the content container to the full row width so the row overflows for
|
|
447
489
|
// iOS to scroll. The inversion flip rides ONLY the outer ScrollView style and each cell, never
|
|
@@ -458,10 +500,13 @@ export function VirtualizedList(props) {
|
|
|
458
500
|
...accessibilityRest,
|
|
459
501
|
style: resolvedStyle,
|
|
460
502
|
contentContainerStyle: resolvedContentContainerStyle,
|
|
461
|
-
horizontal,
|
|
462
503
|
onScroll,
|
|
463
504
|
onLayout: onViewportLayout,
|
|
464
505
|
};
|
|
506
|
+
// `horizontal` is NOT in the bag: the axis is the TAG (`horizontal-scroll-view`), because Android
|
|
507
|
+
// scrolls the two axes with different native ViewManagers. The behavior's own fold deletes the
|
|
508
|
+
// prop and rewrites it from the tag, so passing it would be at best redundant and at worst a
|
|
509
|
+
// contradiction it has to warn about.
|
|
465
510
|
if (onScrollBeginDrag !== undefined)
|
|
466
511
|
scrollProps.onScrollBeginDrag = onScrollBeginDrag;
|
|
467
512
|
if (onScrollEndDrag !== undefined)
|
|
@@ -479,9 +524,6 @@ export function VirtualizedList(props) {
|
|
|
479
524
|
// A pending imperative/initial scroll rides down as contentOffset (fresh identity each push).
|
|
480
525
|
if (commandedOffset !== undefined)
|
|
481
526
|
scrollProps.contentOffset = commandedOffset;
|
|
482
|
-
// Headers in the window stick; an empty list leaves the prop off entirely.
|
|
483
|
-
if (renderedStickyIndices.length > 0)
|
|
484
|
-
scrollProps.stickyHeaderIndices = renderedStickyIndices;
|
|
485
527
|
// Forward maintainVisibleContentPosition to the native ScrollView so it anchors in-window cells.
|
|
486
528
|
// minIndexForVisible is bumped by 1 when a ListHeaderComponent occupies child 0.
|
|
487
529
|
if (maintainVisibleContentPosition !== undefined) {
|
|
@@ -491,16 +533,23 @@ export function VirtualizedList(props) {
|
|
|
491
533
|
(header !== undefined ? 1 : 0),
|
|
492
534
|
};
|
|
493
535
|
}
|
|
494
|
-
// Pull-to-refresh: when onRefresh is set,
|
|
495
|
-
//
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
536
|
+
// Pull-to-refresh: when onRefresh is set, the RefreshControl is an ordinary FIRST CHILD on both
|
|
537
|
+
// platforms rather than a prop. The scroll behavior CLAIMS it, so the engine keeps it beside the
|
|
538
|
+
// content view on iOS and inverts the tree on Android; everything after it lands in the content
|
|
539
|
+
// node the behavior built. refreshing is RN-required alongside onRefresh, default false.
|
|
540
|
+
const refreshControl = onRefresh !== undefined
|
|
541
|
+
? createElement('refresh-control', {
|
|
542
|
+
key: 'refresh-control',
|
|
499
543
|
refreshing: refreshing ?? false,
|
|
500
544
|
onRefresh,
|
|
501
545
|
progressViewOffset,
|
|
502
|
-
})
|
|
546
|
+
})
|
|
547
|
+
: undefined;
|
|
548
|
+
if (refreshControl !== undefined) {
|
|
549
|
+
dlog('VirtualizedList wiring RefreshControl (onRefresh provided)');
|
|
503
550
|
}
|
|
504
|
-
// The
|
|
505
|
-
|
|
551
|
+
// The scroll TAG, not a wrapper: the engine builds the content node, carries
|
|
552
|
+
// `contentContainerStyle` onto it and places the refresh control. `ref` hands back the engine
|
|
553
|
+
// node, which is what `buildScrollViewHandle` drives for the imperative scrolls.
|
|
554
|
+
return createElement(horizontal ? 'horizontal-scroll-view' : 'scroll-view', { ...scrollProps, ref: scrollNodeRef }, refreshControl, ...children);
|
|
506
555
|
}
|
package/build/components.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export interface ITextProps extends IAccessibilityProps, IAriaProps {
|
|
|
42
42
|
numberOfLines?: number;
|
|
43
43
|
ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip';
|
|
44
44
|
selectable?: boolean;
|
|
45
|
+
disabled?: boolean;
|
|
45
46
|
adjustsFontSizeToFit?: boolean;
|
|
46
47
|
minimumFontScale?: number;
|
|
47
48
|
allowFontScaling?: boolean;
|
|
@@ -50,5 +51,3 @@ export interface ITextProps extends IAccessibilityProps, IAriaProps {
|
|
|
50
51
|
ref?: Ref<IHostInstance>;
|
|
51
52
|
children?: ReactNode;
|
|
52
53
|
}
|
|
53
|
-
export declare const View = "symbiote-view";
|
|
54
|
-
export declare const Text = "symbiote-text";
|
package/build/components.js
CHANGED
|
@@ -1,19 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// `descriptorFor` to a Fabric view name at commit.
|
|
5
|
-
|
|
6
|
-
// capitalized tag to the value in scope, and a value that is a STRING is a host element to React —
|
|
7
|
-
// so `<View/>` compiles to `_jsx('symbiote-view', …)` with no component instance, while
|
|
8
|
-
// `JSX.IntrinsicElements['symbiote-view']` still supplies the strict props (a bad prop is TS2322).
|
|
9
|
-
//
|
|
10
|
-
// The two folds their component bodies used to apply both moved down a layer, which is what let
|
|
11
|
-
// the bodies go:
|
|
12
|
-
//
|
|
13
|
-
// aria / accessibility the engine folds every node in `fabricProps` (accessibility-props.ts)
|
|
14
|
-
// id -> nativeID, the renderer folds by spec in `host-config`'s createInstance
|
|
15
|
-
// Text's defaults (`foldHostBag`, driven by HOST_PRIMITIVES)
|
|
16
|
-
//
|
|
17
|
-
// A type annotation rather than `as const`: same literal type, no cast (`ts-js-best-practices`).
|
|
18
|
-
export const View = 'symbiote-view';
|
|
19
|
-
export const Text = 'symbiote-text';
|
|
1
|
+
// The public PROP TYPES for the two strict intrinsics, and nothing else. There is no component and
|
|
2
|
+
// no capitalized alias: an app writes `<view>` / `<text>`, React commits a host element directly,
|
|
3
|
+
// and `JSX.IntrinsicElements` (jsx-runtime.ts) is what supplies these types to it. The reconciler
|
|
4
|
+
// maps the tag through `descriptorFor` to a Fabric view name at commit.
|
|
5
|
+
export {};
|
|
@@ -14,7 +14,7 @@ import { isSymbioteNode, SymbioteSurface, } from '@symbiote-native/engine';
|
|
|
14
14
|
import reconciler from '../host-config.js';
|
|
15
15
|
export function createPortal(children, container, key) {
|
|
16
16
|
if (!(container instanceof SymbioteSurface) && !isSymbioteNode(container)) {
|
|
17
|
-
throw new Error('createPortal target must be an already-mounted host node (e.g. a ref to a rendered <
|
|
17
|
+
throw new Error('createPortal target must be an already-mounted host node (e.g. a ref to a rendered <view>) — got something else. Did you forget `.current`/`.value`, or pass a CSS-selector-style string?');
|
|
18
18
|
}
|
|
19
19
|
// @ts-expect-error @types/react-reconciler's ReactPortal (containerInfo/implementation) and
|
|
20
20
|
// react's own ReactPortal (type/props, a ReactElement) are different interfaces describing the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx } from "@symbiote-native/react/jsx-runtime";
|
|
2
2
|
// createTunnel - the cross-surface answer to createPortal's same-surface-only scope. A real
|
|
3
3
|
// createPortal cannot reach across two separate reconciler roots (see
|
|
4
4
|
// github.com/facebook/react/issues/17147); the fix, same as pmndrs/tunnel-rat, is to not
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// The descriptor→element bridge. A render function in @symbiote-native/components returns a
|
|
2
2
|
// framework-agnostic `Descriptor` tree; this maps it onto React elements. The resulting
|
|
3
|
-
// host element (`
|
|
3
|
+
// host element (`view`, `activity-indicator`, …) flows on through the
|
|
4
4
|
// react-reconciler host config → engine → Fabric, exactly like a hand-written JSX host
|
|
5
5
|
// element.
|
|
6
6
|
import { createElement } from 'react';
|
package/build/host-config.js
CHANGED
|
@@ -16,10 +16,9 @@ import { descriptorFor } from '@symbiote-native/components';
|
|
|
16
16
|
// A bare intrinsic tag has no wrapper to apply RN's per-primitive prop folds (id -> nativeID,
|
|
17
17
|
// Text's ellipsizeMode / allowFontScaling defaults), so the renderer is the layer that must.
|
|
18
18
|
// Shared with every other adapter, driven by the same HOST_PRIMITIVES spec.
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
// where the runtime value is known. Identity for every primitive that declares no alternative.
|
|
19
|
+
// WHICH native view a primitive commits can depend on a prop (TextInput's `multiline`), and that
|
|
20
|
+
// prop can be a runtime value — so the choice is made here, where it is known. Identity for every
|
|
21
|
+
// primitive that declares no alternative.
|
|
23
22
|
import { resolveIntrinsicTag } from '@symbiote-native/components/resolve-intrinsic';
|
|
24
23
|
// React-reserved prop keys that must never reach Fabric. `children` is the element
|
|
25
24
|
// tree (handled via appendChild). `ref`/`key` are React 19 plain props: the reconciler
|
|
@@ -99,17 +98,31 @@ const reconciler = createReconciler({
|
|
|
99
98
|
},
|
|
100
99
|
shouldSetTextContent: () => false,
|
|
101
100
|
createInstance(type, props, _container, hostContext) {
|
|
102
|
-
|
|
101
|
+
// The INTRINSIC tag, kept in a binding rather than inlined, because it is needed twice: once
|
|
102
|
+
// to resolve the Fabric view name and once to hand the engine below. The host-behavior
|
|
103
|
+
// registry is keyed by TAG and never by Fabric name — `pressable` and a plain `View`
|
|
104
|
+
// both resolve to `RCTView`, so keying by the resolved name would put a press machine on every
|
|
105
|
+
// view in the app (`core/engine/src/host-behavior.ts`).
|
|
106
|
+
const tag = resolveIntrinsicTag(type, props);
|
|
107
|
+
const descriptor = descriptorFor(tag);
|
|
103
108
|
if (hostContext.isInsideText && !descriptor.isText) {
|
|
104
|
-
throw new Error(`<${type}> can't be nested inside <
|
|
109
|
+
throw new Error(`<${type}> can't be nested inside <text>`);
|
|
105
110
|
}
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
// The third argument is what makes a host behavior reachable AT ALL on this adapter. Dropping
|
|
112
|
+
// it degrades silently: `createElement`'s default is `tag = component`, so the lookup runs
|
|
113
|
+
// against `RCTView` / `RCTImageView`, matches nothing, and every behavior simply never
|
|
114
|
+
// attaches — no throw, no log, and no test goes red, because React ships no `register` entry
|
|
115
|
+
// today and so has never had a behavior to lose. That absence is exactly what hid this: the
|
|
116
|
+
// other four adapters all pass it (vue `renderer/index.ts`, svelte `dom-shim/element.ts`,
|
|
117
|
+
// solid `renderer.ts`, angular `renderer/index.ts`), and React is the one that did not.
|
|
118
|
+
//
|
|
119
|
+
const node = createElement(descriptor.component, descriptor.isText, tag);
|
|
120
|
+
applyProps(node, props);
|
|
108
121
|
return node;
|
|
109
122
|
},
|
|
110
123
|
createTextInstance(text, _container, hostContext) {
|
|
111
124
|
if (!hostContext.isInsideText) {
|
|
112
|
-
throw new Error(`Text string "${text}" must be rendered inside a <
|
|
125
|
+
throw new Error(`Text string "${text}" must be rendered inside a <text>`);
|
|
113
126
|
}
|
|
114
127
|
return createRawText(text);
|
|
115
128
|
},
|
|
@@ -141,9 +154,7 @@ const reconciler = createReconciler({
|
|
|
141
154
|
// an update. The node keeps its identity — an app's ref stays live — and the commit walk
|
|
142
155
|
// re-creates the Fabric node because its viewName no longer matches the committed one.
|
|
143
156
|
setNodeComponent(node, descriptorFor(resolveIntrinsicTag(type, newProps)).component);
|
|
144
|
-
|
|
145
|
-
// the alias twice while never clearing the raw key.
|
|
146
|
-
applyUpdate(node, foldHostBag(type, oldProps), foldHostBag(type, newProps));
|
|
157
|
+
applyUpdate(node, oldProps, newProps);
|
|
147
158
|
},
|
|
148
159
|
commitTextUpdate(node, _oldText, newText) {
|
|
149
160
|
setText(node, newText);
|
package/build/index.d.ts
CHANGED
|
@@ -1,38 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
import './register';
|
|
2
|
+
export type { ISymbioteIntrinsicTag } from './jsx-runtime';
|
|
3
3
|
export type { IViewProps, ITextProps } from './components';
|
|
4
4
|
export type { IAccessibilityProps, IAriaProps, IAccessibilityRole, IRole, IAccessibilityStateValue, IAccessibilityValue, IAccessibilityActionInfo, } from '@symbiote-native/components';
|
|
5
5
|
export type { IResponderProps } from './utils/responder-props';
|
|
6
|
-
export { Image
|
|
7
|
-
export
|
|
8
|
-
export {
|
|
9
|
-
export type {
|
|
10
|
-
export {
|
|
11
|
-
export type { IScrollViewProps, IScrollViewHandle, } from './components/scroll-view';
|
|
12
|
-
export {
|
|
13
|
-
export type {
|
|
14
|
-
export {
|
|
15
|
-
export type { IInputAccessoryViewProps } from './components/input-accessory-view';
|
|
6
|
+
export { Image } from './modules/image';
|
|
7
|
+
export { setImageSourceResolver } from '@symbiote-native/components';
|
|
8
|
+
export type { IImageProps } from './components/image/image-props';
|
|
9
|
+
export type { IImageSource, IImageSourceProp, IResizeMode, IImageSize, IImageCacheStatus, } from '@symbiote-native/components';
|
|
10
|
+
export type { IImageBackgroundProps } from './components/image-background-props';
|
|
11
|
+
export type { IScrollViewProps, IScrollViewHandle, } from './components/scroll-view/scroll-view-props';
|
|
12
|
+
export type { ITextInputProps } from './components/text-input/text-input-props';
|
|
13
|
+
export type { ITextInputHandle, ITextInputChangeEvent, } from '@symbiote-native/components';
|
|
14
|
+
export type { IInputAccessoryViewProps } from './components/input-accessory-view-props';
|
|
16
15
|
export { KeyboardAvoidingView } from './components/keyboard-avoiding-view';
|
|
17
16
|
export type { IKeyboardAvoidingViewProps, IKeyboardAvoidingBehavior, } from './components/keyboard-avoiding-view';
|
|
18
17
|
export { StatusBar } from './modules/status-bar';
|
|
19
18
|
export type { IStatusBarProps, IStatusBarStyle } from './modules/status-bar';
|
|
20
|
-
export {
|
|
21
|
-
export type {
|
|
22
|
-
export {
|
|
23
|
-
export type {
|
|
24
|
-
export {
|
|
25
|
-
export type { ISafeAreaViewProps } from './components/safe-area-view';
|
|
26
|
-
export { RefreshControl } from './components/refresh-control';
|
|
27
|
-
export type { IRefreshControlProps } from './components/refresh-control';
|
|
19
|
+
export type { ISwitchProps } from './components/switch/switch-props';
|
|
20
|
+
export type { ISwitchTrackColor, ISwitchChangeEvent, } from '@symbiote-native/components';
|
|
21
|
+
export type { IActivityIndicatorProps } from './components/activity-indicator-props';
|
|
22
|
+
export type { ISafeAreaViewProps } from './components/safe-area-view-props';
|
|
23
|
+
export type { IRefreshControlProps } from './components/refresh-control-props';
|
|
28
24
|
export { Modal } from './components/modal';
|
|
29
25
|
export type { IModalProps, IModalAnimationType, IModalPresentationStyle, IModalOrientation, } from './components/modal';
|
|
30
|
-
export {
|
|
31
|
-
export type {
|
|
32
|
-
export {
|
|
33
|
-
export type {
|
|
34
|
-
export { Button } from './components/button';
|
|
35
|
-
export type { IButtonProps } from './components/button';
|
|
26
|
+
export type { IPressableProps, IPressState, } from './components/pressable/pressable-props';
|
|
27
|
+
export type { ITouchableOpacityProps, ITouchableHighlightProps, } from './components/touchable/touchable-props';
|
|
28
|
+
export type { ITouchableWithoutFeedbackProps } from './components/touchable-without-feedback/touchable-without-feedback-props';
|
|
29
|
+
export type { IButtonProps } from './components/button-props';
|
|
36
30
|
export { FlatList } from './components/flat-list';
|
|
37
31
|
export type { IFlatListProps, IFlatListHandle } from './components/flat-list';
|
|
38
32
|
export { SectionList } from './components/section-list';
|
|
@@ -68,7 +62,8 @@ export { PanResponder } from '@symbiote-native/engine';
|
|
|
68
62
|
export type { IPanResponderGestureState, IPanResponderCallbacks, IGestureResponderHandlers, IPanResponderInstance, } from '@symbiote-native/engine';
|
|
69
63
|
export { InteractionManager } from '@symbiote-native/engine';
|
|
70
64
|
export type { IInteractionEvent, ISimpleTask, IPromiseTask, ITask, IHandle, } from '@symbiote-native/engine';
|
|
71
|
-
export { TouchableNativeFeedback } from '
|
|
72
|
-
export type {
|
|
65
|
+
export { TouchableNativeFeedback } from '@symbiote-native/components';
|
|
66
|
+
export type { INativeFeedbackBackground, IThemeAttrBackground, IRippleBackground, } from '@symbiote-native/components';
|
|
67
|
+
export type { ITouchableNativeFeedbackProps } from './components/touchable-native-feedback/touchable-native-feedback-props';
|
|
73
68
|
export type { ISymbioteEvent, ISymbioteNode, IRootTag, } from '@symbiote-native/engine';
|
|
74
69
|
export type { ICellLayout, ISeparatorProps, ISeparators, IModalOrientationChangeEvent, IPressableAndroidRippleConfig, IEnterKeyHint, IInputMode, ISubmitBehavior, ITextInputSelection, IImageStatics, } from '@symbiote-native/components';
|
package/build/index.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
// @symbiote-native/react: a react-reconciler host config (mutation mode) over
|
|
2
2
|
// @symbiote-native/engine. React is a known-good driver: it proves the native pipe
|
|
3
3
|
// and the shared clone-on-write engine before any non-React adapter has to.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
// Bare side-effect import, deliberately NOT a re-export and deliberately not beside one of the
|
|
5
|
+
// same specifier: it installs the engine's host behaviors, which is what makes a bare
|
|
6
|
+
// `<pressable>` / `<text-input>` / `<switch>` carry its machine. Any other shape is dropped by
|
|
7
|
+
// Metro's inlineRequires in a release build — see register.ts.
|
|
8
|
+
import './register.js';
|
|
9
|
+
// `Image` is a TAG — `<image>` — and the name now carries only RN's STATICS
|
|
10
|
+
// (`Image.getSize(...)`), an imperative API with no view. The wrapper's whole source/style
|
|
11
|
+
// translation runs on the tag as the engine's `registerImageBehavior`.
|
|
12
|
+
export { Image } from './modules/image/index.js';
|
|
13
|
+
export { setImageSourceResolver } from '@symbiote-native/components';
|
|
10
14
|
export { KeyboardAvoidingView } from './components/keyboard-avoiding-view/index.js';
|
|
11
15
|
export { StatusBar } from './modules/status-bar';
|
|
12
|
-
export { Switch } from './components/switch';
|
|
13
|
-
export { ActivityIndicator } from './components/activity-indicator';
|
|
14
|
-
export { SafeAreaView } from './components/safe-area-view/index.js';
|
|
15
|
-
export { RefreshControl } from './components/refresh-control/index.js';
|
|
16
16
|
export { Modal } from './components/modal/index.js';
|
|
17
|
-
export { Pressable } from './components/pressable/index.js';
|
|
18
|
-
export { TouchableOpacity, TouchableHighlight, TouchableWithoutFeedback, } from './components/touchable/index.js';
|
|
19
|
-
export { Button } from './components/button.js';
|
|
20
17
|
export { FlatList } from './components/flat-list/index.js';
|
|
21
18
|
export { SectionList } from './components/section-list/index.js';
|
|
22
19
|
export { VirtualizedSectionList } from './components/virtualized-section-list/index.js';
|
|
@@ -74,4 +71,7 @@ export { InteractionManager } from '@symbiote-native/engine';
|
|
|
74
71
|
// Android-only surface (the second-platform pass): a thin JS shim over an Android Fabric view,
|
|
75
72
|
// inert on iOS (no native view -> degrades to a plain container). The Android-only MODULES
|
|
76
73
|
// (ToastAndroid, PermissionsAndroid, BackHandler) sit in the engine block above.
|
|
77
|
-
|
|
74
|
+
// `TouchableNativeFeedback` is now RN's STATIC NAMESPACE, not a component: the element is the tag
|
|
75
|
+
// `<touchable-native-feedback>`, which commits no node of its own and clones onto its single child.
|
|
76
|
+
// `TouchableNativeFeedback.Ripple(…)` / `.SelectableBackground(…)` are unchanged.
|
|
77
|
+
export { TouchableNativeFeedback } from '@symbiote-native/components';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// The dev twin of `./jsx-runtime`, and it has to be its own file rather than an alias of it.
|
|
2
|
+
//
|
|
3
|
+
// TypeScript resolves the namespace from `<jsxImportSource>/jsx-dev-runtime` whenever `jsx` is
|
|
4
|
+
// `react-jsxdev`, and Babel's automatic runtime imports `jsxDEV` — not `jsx`/`jsxs` — from that
|
|
5
|
+
// same path in a development build. Solid points both subpaths at one file because its emitted
|
|
6
|
+
// runtime is empty either way; ours carries real factories, so the two entries export different
|
|
7
|
+
// names and pointing them at one file would leave a dev build importing a `jsxDEV` that is not
|
|
8
|
+
// there.
|
|
9
|
+
export { jsxDEV } from 'react/jsx-dev-runtime';
|
|
10
|
+
export { Fragment } from 'react/jsx-runtime';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const JSX_NAMESPACE_CHECK: number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@symbiote-native/react/jsx-runtime";
|
|
2
|
+
const strictIntrinsicAcceptsItsOwnProp = (_jsx("view", { testID: "jsx-namespace-check" }));
|
|
3
|
+
const strictIntrinsicRejectsAnUnknownProp = (_jsx("view", { definitelyNotAViewProp: 1 }));
|
|
4
|
+
export const JSX_NAMESPACE_CHECK = [
|
|
5
|
+
strictIntrinsicAcceptsItsOwnProp,
|
|
6
|
+
strictIntrinsicRejectsAnUnknownProp,
|
|
7
|
+
].length;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ICrossTypedIntrinsics } from '@symbiote-native/components';
|
|
2
|
+
import type { Key } from 'react';
|
|
3
|
+
import type { IViewProps, ITextProps } from './components';
|
|
4
|
+
import type { IPressableProps } from './components/pressable/pressable-props';
|
|
5
|
+
import type { IButtonProps } from './components/button-props';
|
|
6
|
+
import type { IImageProps } from './components/image/image-props';
|
|
7
|
+
import type { IImageBackgroundProps } from './components/image-background-props';
|
|
8
|
+
import type { IInputAccessoryViewProps } from './components/input-accessory-view-props';
|
|
9
|
+
import type { IRefreshControlProps } from './components/refresh-control-props';
|
|
10
|
+
import type { ISafeAreaViewProps } from './components/safe-area-view-props';
|
|
11
|
+
import type { ITouchableNativeFeedbackProps } from './components/touchable-native-feedback/touchable-native-feedback-props';
|
|
12
|
+
import type { ITouchableOpacityProps, ITouchableHighlightProps } from './components/touchable/touchable-props';
|
|
13
|
+
import type { ITouchableWithoutFeedbackProps } from './components/touchable-without-feedback/touchable-without-feedback-props';
|
|
14
|
+
import type { IScrollViewProps } from './components/scroll-view/scroll-view-props';
|
|
15
|
+
import type { ISwitchProps } from './components/switch/switch-props';
|
|
16
|
+
import type { ITextInputProps } from './components/text-input/text-input-props';
|
|
17
|
+
import type { IModalProps } from './components/modal';
|
|
18
|
+
import type { IActivityIndicatorProps } from './components/activity-indicator-props';
|
|
19
|
+
export { Fragment, jsx, jsxs } from 'react/jsx-runtime';
|
|
20
|
+
interface IHostProps {
|
|
21
|
+
style?: unknown;
|
|
22
|
+
children?: import('react').ReactNode;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface ICrossedPrimitiveProps {
|
|
26
|
+
view: IViewProps;
|
|
27
|
+
text: ITextProps;
|
|
28
|
+
pressable: IPressableProps;
|
|
29
|
+
button: IButtonProps;
|
|
30
|
+
image: IImageProps;
|
|
31
|
+
'image-background': IImageBackgroundProps;
|
|
32
|
+
'input-accessory-view': IInputAccessoryViewProps;
|
|
33
|
+
'refresh-control': IRefreshControlProps;
|
|
34
|
+
'safe-area-view': ISafeAreaViewProps;
|
|
35
|
+
'touchable-native-feedback': ITouchableNativeFeedbackProps;
|
|
36
|
+
'touchable-opacity': ITouchableOpacityProps;
|
|
37
|
+
'touchable-highlight': ITouchableHighlightProps;
|
|
38
|
+
'touchable-without-feedback': ITouchableWithoutFeedbackProps;
|
|
39
|
+
'scroll-view': IScrollViewProps;
|
|
40
|
+
switch: ISwitchProps;
|
|
41
|
+
'text-input': ITextInputProps;
|
|
42
|
+
modal: IModalProps;
|
|
43
|
+
'activity-indicator': IActivityIndicatorProps;
|
|
44
|
+
}
|
|
45
|
+
type IWithKey<Props> = Props & {
|
|
46
|
+
key?: Key | null;
|
|
47
|
+
};
|
|
48
|
+
export declare namespace JSX {
|
|
49
|
+
type ElementType = import('react').JSX.ElementType;
|
|
50
|
+
type Element = import('react').JSX.Element;
|
|
51
|
+
type ElementClass = import('react').JSX.ElementClass;
|
|
52
|
+
type ElementAttributesProperty = import('react').JSX.ElementAttributesProperty;
|
|
53
|
+
type ElementChildrenAttribute = import('react').JSX.ElementChildrenAttribute;
|
|
54
|
+
type LibraryManagedAttributes<C, P> = import('react').JSX.LibraryManagedAttributes<C, P>;
|
|
55
|
+
type IntrinsicAttributes = import('react').JSX.IntrinsicAttributes;
|
|
56
|
+
type IntrinsicClassAttributes<T> = import('react').JSX.IntrinsicClassAttributes<T>;
|
|
57
|
+
interface IntrinsicElements extends ICrossTypedIntrinsics<IHostProps, {
|
|
58
|
+
[K in keyof ICrossedPrimitiveProps]: IWithKey<ICrossedPrimitiveProps[K]>;
|
|
59
|
+
}> {
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export type ISymbioteIntrinsicTag = keyof JSX.IntrinsicElements;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Fragment, jsx, jsxs } from 'react/jsx-runtime';
|