@symbiote-native/components 1.0.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.
- package/README.md +3 -4
- package/build/behaviors/activity-indicator/index.android.d.ts +1 -0
- package/build/behaviors/activity-indicator/index.android.js +16 -0
- package/build/behaviors/activity-indicator/index.d.ts +3 -0
- package/build/behaviors/activity-indicator/index.ios.d.ts +1 -0
- package/build/behaviors/activity-indicator/index.ios.js +14 -0
- package/build/behaviors/activity-indicator/index.js +5 -0
- package/build/behaviors/activity-indicator/shared.d.ts +18 -0
- package/build/behaviors/activity-indicator/shared.js +149 -0
- package/build/behaviors/button.d.ts +2 -0
- package/build/behaviors/button.js +328 -0
- package/build/behaviors/image-background.d.ts +2 -0
- package/build/behaviors/image-background.js +139 -0
- package/build/behaviors/image.d.ts +1 -1
- package/build/behaviors/image.js +2 -2
- package/build/behaviors/input-accessory-view.d.ts +1 -1
- package/build/behaviors/input-accessory-view.js +2 -2
- package/build/behaviors/pressable.d.ts +59 -1
- package/build/behaviors/pressable.js +93 -18
- package/build/behaviors/refresh-control.d.ts +2 -0
- package/build/behaviors/refresh-control.js +83 -0
- package/build/behaviors/scroll-view/index.android.d.ts +1 -0
- package/build/behaviors/scroll-view/index.android.js +52 -0
- package/build/behaviors/scroll-view/index.d.ts +2 -0
- package/build/behaviors/scroll-view/index.ios.d.ts +1 -0
- package/build/behaviors/scroll-view/index.ios.js +10 -0
- package/build/behaviors/scroll-view/index.js +5 -0
- package/build/behaviors/scroll-view/shared.d.ts +11 -0
- package/build/behaviors/scroll-view/shared.js +291 -0
- package/build/behaviors/scroll-view/sticky.d.ts +17 -0
- package/build/behaviors/scroll-view/sticky.js +568 -0
- package/build/behaviors/switch.d.ts +1 -1
- package/build/behaviors/switch.js +9 -5
- package/build/behaviors/text-input.d.ts +2 -2
- package/build/behaviors/text-input.js +43 -15
- package/build/behaviors/touchable-highlight.d.ts +9 -0
- package/build/behaviors/touchable-highlight.js +192 -0
- package/build/behaviors/touchable-native-feedback.d.ts +20 -0
- package/build/behaviors/touchable-native-feedback.js +333 -0
- package/build/behaviors/touchable-opacity.d.ts +12 -0
- package/build/behaviors/touchable-opacity.js +227 -0
- package/build/behaviors/touchable-without-feedback.d.ts +2 -0
- package/build/behaviors/touchable-without-feedback.js +296 -0
- package/build/component-names/index.android.js +29 -19
- package/build/component-names/index.ios.js +31 -19
- package/build/component-names/shared.d.ts +2 -1
- package/build/component-names/shared.js +16 -6
- package/build/descriptor.js +4 -4
- package/build/fold-host-bag.js +2 -2
- package/build/index.d.ts +17 -11
- package/build/index.js +44 -8
- package/build/register.d.ts +1 -0
- package/build/register.js +55 -0
- package/build/scroll-view-commands.d.ts +4 -0
- package/build/scroll-view-commands.js +30 -31
- package/build/state/text-input.d.ts +4 -1
- package/build/view/render-button.d.ts +36 -1
- package/build/view/render-button.js +101 -12
- package/build/view/render-image/index.js +2 -2
- package/build/view/render-input-accessory-view.js +1 -1
- package/build/view/render-modal.js +3 -3
- package/build/view/render-pressable/index.d.ts +2 -0
- package/build/view/render-pressable/index.js +24 -0
- package/build/view/render-scroll-view.d.ts +1 -0
- package/build/view/render-scroll-view.js +18 -9
- package/build/view/render-switch.d.ts +4 -1
- package/build/view/render-switch.js +2 -2
- package/build/view/render-text-input.js +2 -2
- package/build/view/render-touchable-native-feedback.d.ts +19 -0
- package/build/view/render-touchable-native-feedback.js +19 -0
- package/host-primitives.cjs +202 -150
- package/host-primitives.d.cts +0 -2
- package/package.json +8 -17
- package/build/state-style.d.ts +0 -15
- package/build/state-style.js +0 -47
- package/build/view/render-activity-indicator.d.ts +0 -25
- package/build/view/render-activity-indicator.js +0 -88
- package/build/view/render-image-background.d.ts +0 -9
- package/build/view/render-image-background.js +0 -48
- package/lowering-fixtures.cjs +0 -259
- package/lowering-fixtures.d.cts +0 -17
- package/specialize-state-style.cjs +0 -219
- package/specialize-state-style.d.cts +0 -15
|
@@ -2,33 +2,45 @@
|
|
|
2
2
|
// (component-names.ts re-exports it) for headless tsx / tsc / web fallback.
|
|
3
3
|
// Fabric names are the codegen spec's registered name (the new-arch name), not the legacy
|
|
4
4
|
// paperComponentName (RCTSwitch, …).
|
|
5
|
+
import { ANCHOR_COMPONENT } from '@symbiote-native/engine';
|
|
5
6
|
import { buildDescriptors, makeDescriptorFor, } from './shared.js';
|
|
6
7
|
const IOS_NAMES = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
'
|
|
12
|
-
|
|
8
|
+
view: 'RCTView',
|
|
9
|
+
pressable: 'RCTView',
|
|
10
|
+
'touchable-opacity': 'RCTView',
|
|
11
|
+
// NOT a view name — TNF commits nothing at all. See `shared.ts`. Platform-invariant, unlike
|
|
12
|
+
// every other entry here: RN's TNF renders no view on either platform, it only stops CLONING a
|
|
13
|
+
// background off Android (TouchableNativeFeedback.js:402).
|
|
14
|
+
'touchable-native-feedback': ANCHOR_COMPONENT,
|
|
15
|
+
'touchable-without-feedback': ANCHOR_COMPONENT,
|
|
16
|
+
'touchable-highlight': 'RCTView',
|
|
17
|
+
button: 'RCTView',
|
|
18
|
+
text: 'RCTText',
|
|
19
|
+
image: 'RCTImageView',
|
|
20
|
+
'image-background': 'RCTView',
|
|
21
|
+
'scroll-view': 'RCTScrollView',
|
|
22
|
+
'scroll-content': 'RCTScrollContentView',
|
|
13
23
|
// iOS uses one scroll view for both axes; horizontal is RCTScrollView with the
|
|
14
24
|
// `horizontal` prop set, so these resolve identically to the vertical pair.
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
25
|
+
'horizontal-scroll-view': 'RCTScrollView',
|
|
26
|
+
'horizontal-scroll-content': 'RCTScrollContentView',
|
|
27
|
+
'text-input': 'RCTSinglelineTextInputView',
|
|
28
|
+
'text-input-multiline': 'RCTMultilineTextInputView',
|
|
19
29
|
// The component path's pair — same native views, a tag the behavior registry does not
|
|
20
30
|
// carry. See `shared.ts` for why the wrapper may not share the lowered tag.
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
|
|
31
|
+
'text-input-managed': 'RCTSinglelineTextInputView',
|
|
32
|
+
'text-input-multiline-managed': 'RCTMultilineTextInputView',
|
|
33
|
+
switch: 'Switch',
|
|
24
34
|
// The wrapper's tag — same native view, a tag the behavior registry does not carry. See
|
|
25
35
|
// `shared.ts` for why the wrapper may not share the lowered tag.
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
|
|
31
|
-
'
|
|
36
|
+
'switch-managed': 'Switch',
|
|
37
|
+
'activity-indicator': 'RCTView',
|
|
38
|
+
'activity-indicator-spinner': 'ActivityIndicatorView',
|
|
39
|
+
'safe-area-view': 'SafeAreaView',
|
|
40
|
+
modal: 'ModalHostView',
|
|
41
|
+
'refresh-control': 'PullToRefreshView',
|
|
42
|
+
'sticky-header': 'RCTView',
|
|
43
|
+
'input-accessory-view': 'RCTInputAccessoryView',
|
|
32
44
|
};
|
|
33
45
|
export const COMPONENT_DESCRIPTORS = buildDescriptors(IOS_NAMES);
|
|
34
46
|
export const descriptorFor = makeDescriptorFor(COMPONENT_DESCRIPTORS);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export type ISymbioteIntrinsic = '
|
|
1
|
+
export type ISymbioteIntrinsic = 'view' | 'pressable' | 'touchable-opacity' | 'touchable-native-feedback' | 'touchable-without-feedback' | 'touchable-highlight' | 'button' | 'text' | 'image' | 'image-background' | 'scroll-view' | 'scroll-content' | 'horizontal-scroll-view' | 'horizontal-scroll-content' | 'text-input' | 'text-input-multiline' | 'text-input-managed' | 'text-input-multiline-managed' | 'switch' | 'switch-managed' | 'activity-indicator' | 'activity-indicator-spinner' | 'safe-area-view' | 'modal' | 'refresh-control' | 'sticky-header' | 'input-accessory-view';
|
|
2
|
+
export type ICrossTypedIntrinsics<LooseProps, Crossed extends Partial<Record<ISymbioteIntrinsic, unknown>>> = Omit<Record<ISymbioteIntrinsic, LooseProps>, keyof Crossed> & Crossed;
|
|
2
3
|
export interface IComponentDescriptor {
|
|
3
4
|
component: string;
|
|
4
5
|
isText: boolean;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// The only text-laying intrinsic; drives the RCTText / RCTVirtualText nesting choice
|
|
8
8
|
// (a <Text> inside another <Text> becomes a virtual span). Platform-invariant, so it is
|
|
9
9
|
// not part of the per-platform name table.
|
|
10
|
-
const TEXT_INTRINSICS = new Set(['
|
|
10
|
+
const TEXT_INTRINSICS = new Set(['text']);
|
|
11
11
|
// Assemble the descriptor map a platform file exports: each intrinsic's Fabric name from
|
|
12
12
|
// the platform table, paired with its invariant isText flag.
|
|
13
13
|
export function buildDescriptors(names) {
|
|
@@ -32,12 +32,23 @@ export function makeDescriptorFor(descriptors) {
|
|
|
32
32
|
const descriptor = descriptors[type];
|
|
33
33
|
if (descriptor !== undefined)
|
|
34
34
|
return descriptor;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
// NO "unknown tag of ours" throw any more, and the reason is the whole cost of dropping the
|
|
36
|
+
// prefix: `symbiote-*` was a MARKER, so a miss carrying it could only be our own typo. Without
|
|
37
|
+
// it this namespace holds three populations that a string cannot tell apart —
|
|
38
|
+
//
|
|
39
|
+
// view · scroll-view ours
|
|
40
|
+
// counter-child · app-root an Angular app's OWN component selectors, kebab by convention
|
|
41
|
+
// RCTView · RNCSlider a Fabric view name, resolving through the fallthrough below
|
|
42
|
+
//
|
|
43
|
+
// — and the first attempt at a replacement ("lowercase is ours") threw on the second row, which
|
|
44
|
+
// is most of an Angular app. Measured: 222 tests, the primary failure being `counter-child`.
|
|
45
|
+
//
|
|
46
|
+
// What replaces it is stronger and is not runtime at all: `ISymbioteIntrinsic` is a closed
|
|
47
|
+
// union, so a misspelled tag in our own source is a compile error at every call site that names
|
|
48
|
+
// one. The guard was only ever a backstop for a name built dynamically.
|
|
38
49
|
if (unrewritten.has(type)) {
|
|
39
50
|
throw new Error(`"${type}" is a primitive's PUBLIC name, not a Fabric view name — a rewrite was missed. ` +
|
|
40
|
-
`Expected the intrinsic tag (e.g. "
|
|
51
|
+
`Expected the intrinsic tag (e.g. "view"). Falling through would have committed ` +
|
|
41
52
|
`a Fabric view literally named "${type}", which fails on device only.`);
|
|
42
53
|
}
|
|
43
54
|
return { component: type, isText: false };
|
|
@@ -64,7 +75,6 @@ function publicNamesThatAreNotViewNames(descriptors) {
|
|
|
64
75
|
const names = new Set();
|
|
65
76
|
for (const intrinsic of Object.keys(descriptors)) {
|
|
66
77
|
const publicName = intrinsic
|
|
67
|
-
.slice('symbiote-'.length)
|
|
68
78
|
.split('-')
|
|
69
79
|
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
70
80
|
.join('');
|
package/build/descriptor.js
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
// adapter's host element then flows on through its reconciler → engine → Fabric.
|
|
5
5
|
//
|
|
6
6
|
// `type` is an open host-component string, not a closed two-member union, because
|
|
7
|
-
// symbiote paints one host element PER native component (`
|
|
8
|
-
// `
|
|
9
|
-
// el(): a host element of any type. txt(): shorthand for the `
|
|
7
|
+
// symbiote paints one host element PER native component (`activity-indicator`,
|
|
8
|
+
// `switch`, …), not just a generic box/text pair.
|
|
9
|
+
// el(): a host element of any type. txt(): shorthand for the `text` primitive.
|
|
10
10
|
export function el(type, props = {}, children = [], key) {
|
|
11
11
|
return { type, props, children, key };
|
|
12
12
|
}
|
|
13
13
|
export function txt(props = {}, children = []) {
|
|
14
|
-
return { type: '
|
|
14
|
+
return { type: 'text', props, children };
|
|
15
15
|
}
|
|
16
16
|
// `bridge` names the caller (`descriptorToSolid`, `descriptorToSvelte`) so a device log says which
|
|
17
17
|
// one tripped without a stack to read.
|
package/build/fold-host-bag.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// `<View>` it refused the wrapper folds it covered by the wrapper
|
|
9
9
|
// a hand-authored tag nobody folds it covered by NOTHING
|
|
10
10
|
//
|
|
11
|
-
// The third path is not hypothetical: Svelte's `components/button.svelte` writes `<
|
|
11
|
+
// The third path is not hypothetical: Svelte's `components/button.svelte` writes `<text>`
|
|
12
12
|
// directly rather than composing `Text.svelte`, so its title reached Fabric with no
|
|
13
13
|
// `ellipsizeMode` and clipped mid-word where every other adapter ellipsised (2026-08-31). Angular
|
|
14
14
|
// shipped the identical defect from the identical cause, and both fixed it the same way — a seed
|
|
@@ -34,7 +34,7 @@ const managedSpellingOf = (tag) => `${tag}-managed`;
|
|
|
34
34
|
// EVERY spelling a primitive commits under, and the two axes are independent.
|
|
35
35
|
//
|
|
36
36
|
// `intrinsicWhen` lets one primitive commit two different tags (`TextInput` ->
|
|
37
|
-
// `
|
|
37
|
+
// `text-input` / `…-multiline`). `-managed` is the wrapper's twin of each of those. A map
|
|
38
38
|
// keyed on the lowered spellings alone folds the lowered path and silently skips the component one
|
|
39
39
|
// — which is exactly what shipped: TextInput and Switch committed a raw `id`, a key no ViewConfig
|
|
40
40
|
// declares, so Fabric dropped it and the nativeID was lost on device with nothing red. Found by
|
package/build/index.d.ts
CHANGED
|
@@ -8,17 +8,15 @@ export type { IEllipsizeMode, ITextDefaultableProps } from './text-props';
|
|
|
8
8
|
export type { IAccessibilityProps, IAriaProps, IAccessibilityRole, IRole, IAccessibilityStateValue, IAccessibilityValue, IAccessibilityActionInfo, } from './accessibility-props';
|
|
9
9
|
export { descriptorFor, COMPONENT_DESCRIPTORS } from './component-names';
|
|
10
10
|
export { buildDescriptors, makeDescriptorFor } from './component-names/shared';
|
|
11
|
-
export type { ISymbioteIntrinsic, IComponentDescriptor, } from './component-names/shared';
|
|
12
|
-
export { renderActivityIndicator } from './view/render-activity-indicator';
|
|
13
|
-
export type { IActivityIndicatorProps, IActivityIndicatorViewProps, IActivityIndicatorPlatform, IActivityIndicatorSize, } from './view/render-activity-indicator';
|
|
11
|
+
export type { ISymbioteIntrinsic, IComponentDescriptor, ICrossTypedIntrinsics, } from './component-names/shared';
|
|
14
12
|
export { renderSwitch } from './view/render-switch';
|
|
15
|
-
export type { ISwitchProps, ISwitchViewProps, ISwitchPlatform, ISwitchTrackColor, } from './view/render-switch';
|
|
13
|
+
export type { ISwitchProps, ISwitchViewProps, ISwitchPlatform, ISwitchTrackColor, ISwitchChangeEvent, } from './view/render-switch';
|
|
16
14
|
export type { IResponderProps } from './responder-props';
|
|
17
15
|
export { switchReducer, createInitialSwitchState, shouldSnapBack, valueFromChange, } from './state/switch';
|
|
18
16
|
export type { ISwitchState, ISwitchAction } from './state/switch';
|
|
19
17
|
export { resolveDecelerationRate, selectScrollIntrinsics, readLayoutDimension, didContentSizeChange, resolveScrollForwarding, SCROLL_VIEW_BASE_HORIZONTAL, SCROLL_VIEW_BASE_VERTICAL, } from './view/render-scroll-view';
|
|
20
18
|
export type { IScrollIntrinsics, IContentSize, IScrollForwarding, IScrollForwardingInputs, IScrollForwardMode, } from './view/render-scroll-view';
|
|
21
|
-
export { buildScrollViewHandle, splitLayoutProps, attachStickyScroll, isSymbioteEvent, forwardScrollEvent, } from './scroll-view-commands';
|
|
19
|
+
export { buildScrollViewHandle, splitLayoutProps, splitScrollViewStyle, attachStickyScroll, isSymbioteEvent, forwardScrollEvent, } from './scroll-view-commands';
|
|
22
20
|
export type { IScrollViewHandle } from './scroll-view-commands';
|
|
23
21
|
export { computeStickyInterpolation, nextStickyHeaderY, stickyDebounceMs, readLayoutNumber, STICKY_HEADER_Z_INDEX, } from './view/render-scroll-sticky';
|
|
24
22
|
export type { IStickyHeaderProps, IStickyInterpolationParams, } from './view/render-scroll-sticky';
|
|
@@ -28,8 +26,6 @@ export type { IImageSource, IImageSourceProp, IResizeMode, IImageProps, IImageVi
|
|
|
28
26
|
export { renderImage } from './view/render-image';
|
|
29
27
|
export type { IImageStatics, IImageSize, IImageCacheStatus, } from '@symbiote-native/engine';
|
|
30
28
|
export { imageStatics, setImageSourceResolver } from '@symbiote-native/engine';
|
|
31
|
-
export { renderImageBackground } from './view/render-image-background';
|
|
32
|
-
export type { IImageBackgroundViewProps } from './view/render-image-background';
|
|
33
29
|
export { renderInputAccessoryView } from './view/render-input-accessory-view';
|
|
34
30
|
export type { IInputAccessoryViewViewProps } from './view/render-input-accessory-view';
|
|
35
31
|
export { renderModal } from './view/render-modal';
|
|
@@ -40,17 +36,17 @@ export { computeInset, keyboardAvoidingEventNamesFor, readPrefersCrossFadeTransi
|
|
|
40
36
|
export type { IComputeInsetOptions, IKeyboardAvoidingBehavior, IKeyboardAvoidingEventNames, IMeasuredFrame, IKeyboardFrame, IKeyboardAvoidingLayout, IResolveKeyboardAvoidingLayoutParams, } from './view/render-keyboard-avoiding-view';
|
|
41
37
|
export { createPressHandlers, createPressRuntime, disposePressRuntime, normalizeRect, maxEdge, isTouchWithinRegion, readPoint, computeRegion, rippleProps, DEFAULT_DELAY_LONG_PRESS_MS, DEFAULT_MIN_PRESS_DURATION_MS, DEFAULT_PRESS_RECT_OFFSETS, } from './state/pressable';
|
|
42
38
|
export type { IPressState, IPressHandler, IPressHandlers, IPressHost, IPressRuntime, IPressMachineConfig, IFrameCallback, IRectOffset, IEdgeInsets, IResponderRegion, IPressableAndroidRippleConfig, IRippleBackground as IPressableRippleBackground, } from './state/pressable';
|
|
43
|
-
export { buildPressableListeners, resolveDisabledAccessibilityState, noteHoverNoop, shouldSuppressPress, shouldClaimResponder, isTerminationAllowed, } from './view/render-pressable';
|
|
39
|
+
export { buildPressableListeners, resolveDisabledAccessibilityState, noteHoverNoop, shouldSuppressPress, shouldClaimResponder, isTerminationAllowed, resolvePressableFocusable, resolveTouchableFocusable, } from './view/render-pressable';
|
|
44
40
|
export { computePressOutWait, createTouchableFeedbackRuntime, createTouchableFeedbackHandlers, DEFAULT_ACTIVE_OPACITY, OPACITY_ACTIVE_GRANT_DURATION_MS, OPACITY_ACTIVE_DURATION_MS, OPACITY_INACTIVE_DURATION_MS, RESTING_OPACITY, DEFAULT_HIGHLIGHT_CHILD_OPACITY, DEFAULT_UNDERLAY_COLOR, TOUCHABLE_MIN_PRESS_DURATION_MS, restingOpacityFromStyle, hasTouchablePressHandler, createHighlightUnderlayRuntime, createHighlightUnderlayHandlers, } from './state/touchable';
|
|
45
41
|
export type { IPressTimingProps, ITouchableHandler, ITouchableFeedbackRuntime, ITouchableFeedbackConfig, ITouchableFeedbackCallbacks, ITouchableFeedbackHandlers, ITouchablePressHandlerProps, IHighlightUnderlayRuntime, IHighlightUnderlayConfig, IHighlightUnderlayCallbacks, IHighlightUnderlayHandlers, } from './state/touchable';
|
|
46
42
|
export { resolveHighlightExtraStyles } from './view/render-touchable-highlight';
|
|
47
43
|
export type { ITouchableHighlightExtraStyles, ITouchableHighlightUnderlayView, } from './view/render-touchable-highlight';
|
|
48
|
-
export { backgroundProps, canUseNativeForeground, selectableBackground, selectableBackgroundBorderless, rippleBackground, } from './view/render-touchable-native-feedback';
|
|
44
|
+
export { backgroundProps, canUseNativeForeground, selectableBackground, selectableBackgroundBorderless, rippleBackground, TouchableNativeFeedback, } from './view/render-touchable-native-feedback';
|
|
49
45
|
export type { INativeFeedbackBackground, IThemeAttrBackground, IRippleBackground, } from './view/render-touchable-native-feedback';
|
|
50
|
-
export { BUTTON_ACCESSIBILITY_ROLE, buttonTextStyle, resolveButtonTextStyle, } from './view/render-button';
|
|
46
|
+
export { BUTTON_ACCESSIBILITY_ROLE, buttonTextStyle, buttonViewStyle, resolveButtonDisabled, resolveButtonImportantForAccessibility, resolveButtonTextStyle, resolveButtonTitle, resolveButtonViewStyle, } from './view/render-button';
|
|
51
47
|
export type { IButtonProps } from './view/render-button';
|
|
52
48
|
export { resolveTextInputProps, foldText, foldAutoComplete, foldSubmitBehavior, mapAutoComplete, textFromChange, eventCountFromChange, shouldCommandText, INITIAL_EVENT_COUNT, SELECTION_NONE, } from './state/text-input';
|
|
53
|
-
export type { ITextInputProps, ITextInputHandle, ITextInputSelection, ITextInputEventHandler, ITextInputFoldInput, IFoldedTextInputProps, IInputMode, IEnterKeyHint, ISubmitBehavior, } from './state/text-input';
|
|
49
|
+
export type { ITextInputProps, ITextInputHandle, ITextInputSelection, ITextInputEventHandler, ITextInputFoldInput, IFoldedTextInputProps, IInputMode, IEnterKeyHint, ISubmitBehavior, ITextInputChangeEvent, } from './state/text-input';
|
|
54
50
|
export { keyboardTypeForInputMode } from './state/text-input';
|
|
55
51
|
export { renderTextInput } from './view/render-text-input';
|
|
56
52
|
export type { ITextInputViewProps } from './view/render-text-input';
|
|
@@ -65,7 +61,17 @@ export type { IRow } from './state/flat-list';
|
|
|
65
61
|
export { flattenSections, unwrapEntryItem, sectionEntryKey, scrollLocationToFlatIndex, } from './state/section-list';
|
|
66
62
|
export type { ISection, ISectionEntry, IVirtualizedSectionListHandle, } from './state/section-list';
|
|
67
63
|
export { registerPressableBehavior, PRESSABLE_TAG, } from './behaviors/pressable';
|
|
64
|
+
export { registerTouchableOpacityBehavior, TOUCHABLE_OPACITY_TAG, } from './behaviors/touchable-opacity';
|
|
65
|
+
export { registerTouchableHighlightBehavior, TOUCHABLE_HIGHLIGHT_TAG, } from './behaviors/touchable-highlight';
|
|
66
|
+
export { registerButtonBehavior, BUTTON_TAG } from './behaviors/button';
|
|
67
|
+
export { registerTouchableNativeFeedbackBehavior, TOUCHABLE_NATIVE_FEEDBACK_TAG, } from './behaviors/touchable-native-feedback';
|
|
68
|
+
export { registerTouchableWithoutFeedbackBehavior, TOUCHABLE_WITHOUT_FEEDBACK_TAG, } from './behaviors/touchable-without-feedback';
|
|
69
|
+
export { ACTIVITY_INDICATOR_SPINNER_TAG, ACTIVITY_INDICATOR_TAG, registerActivityIndicatorBehavior, } from './behaviors/activity-indicator';
|
|
70
|
+
export type { IActivityIndicatorProps, IActivityIndicatorSize, } from './behaviors/activity-indicator';
|
|
68
71
|
export { foldImagePayload, IMAGE_TAG, registerImageBehavior, } from './behaviors/image';
|
|
72
|
+
export { IMAGE_BACKGROUND_TAG, registerImageBackgroundBehavior, } from './behaviors/image-background';
|
|
69
73
|
export { foldInputAccessoryViewPayload, INPUT_ACCESSORY_VIEW_TAG, registerInputAccessoryViewBehavior, } from './behaviors/input-accessory-view';
|
|
70
74
|
export { registerTextInputBehavior, buildTextInputHandle, TEXT_INPUT_TAG, TEXT_INPUT_MULTILINE_TAG, } from './behaviors/text-input';
|
|
71
75
|
export { registerSwitchBehavior, SWITCH_TAG } from './behaviors/switch';
|
|
76
|
+
export { registerRefreshControlBehavior, REFRESH_CONTROL_TAG, } from './behaviors/refresh-control';
|
|
77
|
+
export { HORIZONTAL_SCROLL_VIEW_TAG, registerScrollViewBehavior, SCROLL_VIEW_TAG, } from './behaviors/scroll-view';
|
package/build/index.js
CHANGED
|
@@ -18,7 +18,6 @@ export { resolveTextProps } from './text-props.js';
|
|
|
18
18
|
// re-exports iOS for headless. descriptorFor is the per-platform-bound resolver.
|
|
19
19
|
export { descriptorFor, COMPONENT_DESCRIPTORS } from './component-names';
|
|
20
20
|
export { buildDescriptors, makeDescriptorFor } from './component-names/shared.js';
|
|
21
|
-
export { renderActivityIndicator } from './view/render-activity-indicator.js';
|
|
22
21
|
export { renderSwitch } from './view/render-switch.js';
|
|
23
22
|
// Switch is the first STATE machine off this layer (ActivityIndicator was render-only):
|
|
24
23
|
// the reducer + the two pure predicates are the logic half, the adapter supplies the hook.
|
|
@@ -27,7 +26,7 @@ export { switchReducer, createInitialSwitchState, shouldSnapBack, valueFromChang
|
|
|
27
26
|
// owns the refs/effects/element assembly and the sticky-header component; these supply the
|
|
28
27
|
// platform-invariant math and plumbing every adapter shares.
|
|
29
28
|
export { resolveDecelerationRate, selectScrollIntrinsics, readLayoutDimension, didContentSizeChange, resolveScrollForwarding, SCROLL_VIEW_BASE_HORIZONTAL, SCROLL_VIEW_BASE_VERTICAL, } from './view/render-scroll-view.js';
|
|
30
|
-
export { buildScrollViewHandle, splitLayoutProps, attachStickyScroll, isSymbioteEvent, forwardScrollEvent, } from './scroll-view-commands.js';
|
|
29
|
+
export { buildScrollViewHandle, splitLayoutProps, splitScrollViewStyle, attachStickyScroll, isSymbioteEvent, forwardScrollEvent, } from './scroll-view-commands.js';
|
|
31
30
|
export { computeStickyInterpolation, nextStickyHeaderY, stickyDebounceMs, readLayoutNumber, STICKY_HEADER_Z_INDEX, } from './view/render-scroll-sticky.js';
|
|
32
31
|
// The per-header sticky effect machine: the one pure state machine every sticky-header consumer drives
|
|
33
32
|
// (React/Vue header component, Angular header component, Angular projection wrapper), folding the
|
|
@@ -37,7 +36,8 @@ export { reduceSticky, createInitialStickyState, stickyEffectSignature, } from '
|
|
|
37
36
|
export { renderImage } from './view/render-image/index.js';
|
|
38
37
|
export { imageStatics, setImageSourceResolver } from '@symbiote-native/engine';
|
|
39
38
|
// ImageBackground: render-only composition (absolute-fill image behind, children on top).
|
|
40
|
-
|
|
39
|
+
// No render fn: the only composition this primitive had is the two nodes the behavior builds, so
|
|
40
|
+
// `view/render-image-background.ts` went with the wrappers — same as ActivityIndicator's.
|
|
41
41
|
// InputAccessoryView: render-only host assembly (nativeID/backgroundColor).
|
|
42
42
|
export { renderInputAccessoryView } from './view/render-input-accessory-view.js';
|
|
43
43
|
// Modal: full 3-layer split (state machine gates the iOS keep-alive frame).
|
|
@@ -50,15 +50,19 @@ export { computeInset, keyboardAvoidingEventNamesFor, readPrefersCrossFadeTransi
|
|
|
50
50
|
// accessibilityState + ripple render decisions in view/render-pressable. Every adapter supplies
|
|
51
51
|
// only its reactive `pressed` cell + the View's measure handle (see the 3-layer split).
|
|
52
52
|
export { createPressHandlers, createPressRuntime, disposePressRuntime, normalizeRect, maxEdge, isTouchWithinRegion, readPoint, computeRegion, rippleProps, DEFAULT_DELAY_LONG_PRESS_MS, DEFAULT_MIN_PRESS_DURATION_MS, DEFAULT_PRESS_RECT_OFFSETS, } from './state/pressable.js';
|
|
53
|
-
export { buildPressableListeners, resolveDisabledAccessibilityState, noteHoverNoop, shouldSuppressPress, shouldClaimResponder, isTerminationAllowed, } from './view/render-pressable/index.js';
|
|
53
|
+
export { buildPressableListeners, resolveDisabledAccessibilityState, noteHoverNoop, shouldSuppressPress, shouldClaimResponder, isTerminationAllowed, resolvePressableFocusable, resolveTouchableFocusable, } from './view/render-pressable/index.js';
|
|
54
54
|
// Touchable*: shared press-timing constants + the deactivation-floor math (the Animated feedback
|
|
55
55
|
// itself stays per-adapter), and TouchableNativeFeedback's pure static factories + background map.
|
|
56
56
|
export { computePressOutWait, createTouchableFeedbackRuntime, createTouchableFeedbackHandlers, DEFAULT_ACTIVE_OPACITY, OPACITY_ACTIVE_GRANT_DURATION_MS, OPACITY_ACTIVE_DURATION_MS, OPACITY_INACTIVE_DURATION_MS, RESTING_OPACITY, DEFAULT_HIGHLIGHT_CHILD_OPACITY, DEFAULT_UNDERLAY_COLOR, TOUCHABLE_MIN_PRESS_DURATION_MS, restingOpacityFromStyle, hasTouchablePressHandler, createHighlightUnderlayRuntime, createHighlightUnderlayHandlers, } from './state/touchable.js';
|
|
57
57
|
export { resolveHighlightExtraStyles } from './view/render-touchable-highlight.js';
|
|
58
|
-
export { backgroundProps, canUseNativeForeground, selectableBackground, selectableBackgroundBorderless, rippleBackground,
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
|
|
58
|
+
export { backgroundProps, canUseNativeForeground, selectableBackground, selectableBackgroundBorderless, rippleBackground,
|
|
59
|
+
// RN's own static namespace, the only part of the deleted wrappers with nowhere else to go: the
|
|
60
|
+
// element is a tag now, and a tag is a string that cannot carry `.Ripple`.
|
|
61
|
+
TouchableNativeFeedback, } from './view/render-touchable-native-feedback.js';
|
|
62
|
+
// Button: the role constant plus every platform fold RN's Button.js performs (the adapter composes
|
|
63
|
+
// its own touchable + view + text around them). The VIEW style is the half that was missing until
|
|
64
|
+
// 2026-09-09 and it is the whole Android look.
|
|
65
|
+
export { BUTTON_ACCESSIBILITY_ROLE, buttonTextStyle, buttonViewStyle, resolveButtonDisabled, resolveButtonImportantForAccessibility, resolveButtonTextStyle, resolveButtonTitle, resolveButtonViewStyle, } from './view/render-button.js';
|
|
62
66
|
// TextInput: the controlled-value / event-count handshake. The logic half is the pure
|
|
63
67
|
// folds/maps + the controlled-write predicate (not a single reducer: count must re-render the
|
|
64
68
|
// imperative handle, lastNativeText must not); the view half picks the intrinsic and maps the
|
|
@@ -80,7 +84,39 @@ export { subscribeListDiagnostics } from './state/virtualized-list-diagnostics.j
|
|
|
80
84
|
export { SINGLE_COLUMN, chunkIntoRows, rowKeyExtractor, expandRowToken, expandRowViewability, lastItemOfRow, firstItemOfRow, } from './state/flat-list.js';
|
|
81
85
|
export { flattenSections, unwrapEntryItem, sectionEntryKey, scrollLocationToFlatIndex, } from './state/section-list.js';
|
|
82
86
|
export { registerPressableBehavior, PRESSABLE_TAG, } from './behaviors/pressable.js';
|
|
87
|
+
export { registerTouchableOpacityBehavior, TOUCHABLE_OPACITY_TAG, } from './behaviors/touchable-opacity.js';
|
|
88
|
+
export { registerTouchableHighlightBehavior, TOUCHABLE_HIGHLIGHT_TAG, } from './behaviors/touchable-highlight.js';
|
|
89
|
+
export { registerButtonBehavior, BUTTON_TAG } from './behaviors/button.js';
|
|
90
|
+
// Registered by ALL FIVE adapters since 2026-09-09, in the same commit that deleted the five
|
|
91
|
+
// wrappers — which is what makes it safe. While those wrappers still rendered a `Pressable` around
|
|
92
|
+
// a feedback `View`, registering would have put a second responder on every existing
|
|
93
|
+
// TouchableNativeFeedback. The ActivityIndicator and ScrollView blocks below are still in the
|
|
94
|
+
// withheld state this one just left.
|
|
95
|
+
export { registerTouchableNativeFeedbackBehavior, TOUCHABLE_NATIVE_FEEDBACK_TAG, } from './behaviors/touchable-native-feedback.js';
|
|
96
|
+
// The second tag that commits no node, and registered by all five adapters in the same commit that
|
|
97
|
+
// deleted their five wrappers — while those wrappers still rendered a `Pressable` around the app's
|
|
98
|
+
// children, registering would have put a second responder on every TouchableWithoutFeedback.
|
|
99
|
+
export { registerTouchableWithoutFeedbackBehavior, TOUCHABLE_WITHOUT_FEEDBACK_TAG, } from './behaviors/touchable-without-feedback.js';
|
|
100
|
+
// Registered by all five adapters since 2026-09-09, in the same commit that deleted the five
|
|
101
|
+
// wrappers — the tag builds its own spinner, so a surviving wrapper would have painted a second one.
|
|
102
|
+
// The prop type rides along: there is no `view/render-activity-indicator.ts` any more, because the
|
|
103
|
+
// only render this primitive had was the two nodes the behavior now builds.
|
|
104
|
+
export { ACTIVITY_INDICATOR_SPINNER_TAG, ACTIVITY_INDICATOR_TAG, registerActivityIndicatorBehavior, } from './behaviors/activity-indicator';
|
|
83
105
|
export { foldImagePayload, IMAGE_TAG, registerImageBehavior, } from './behaviors/image.js';
|
|
106
|
+
// Registered by all five adapters since 2026-09-09, in the same commit that deleted the five
|
|
107
|
+
// wrappers — the tag builds the background image itself, so a surviving wrapper would have
|
|
108
|
+
// committed a second one under it.
|
|
109
|
+
export { IMAGE_BACKGROUND_TAG, registerImageBackgroundBehavior, } from './behaviors/image-background.js';
|
|
84
110
|
export { foldInputAccessoryViewPayload, INPUT_ACCESSORY_VIEW_TAG, registerInputAccessoryViewBehavior, } from './behaviors/input-accessory-view.js';
|
|
85
111
|
export { registerTextInputBehavior, buildTextInputHandle, TEXT_INPUT_TAG, TEXT_INPUT_MULTILINE_TAG, } from './behaviors/text-input.js';
|
|
86
112
|
export { registerSwitchBehavior, SWITCH_TAG } from './behaviors/switch.js';
|
|
113
|
+
export { registerRefreshControlBehavior, REFRESH_CONTROL_TAG, } from './behaviors/refresh-control.js';
|
|
114
|
+
// Exported as a FUNCTION, not as a side-effect module, which is what keeps it safe on a barrel:
|
|
115
|
+
// Metro's inlineRequires only defers a re-export until its binding is named as a VALUE, and a
|
|
116
|
+
// caller of `registerScrollViewBehavior()` names it. The shape CLAUDE.md forbids is a module whose
|
|
117
|
+
// evaluation alone registers.
|
|
118
|
+
//
|
|
119
|
+
// EVERY ADAPTER CALLS IT since 2026-09-11, through `@symbiote-native/components/register`. It was
|
|
120
|
+
// withheld while the wrappers built their own content node — registering then would have
|
|
121
|
+
// double-nested every ScrollView. They are gone; the engine is the single owner.
|
|
122
|
+
export { HORIZONTAL_SCROLL_VIEW_TAG, registerScrollViewBehavior, SCROLL_VIEW_TAG, } from './behaviors/scroll-view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Side-effect ONLY. Exports nothing, and must never be re-exported from any barrel.
|
|
2
|
+
//
|
|
3
|
+
// The engine's host-behavior registry is what makes a bare `<pressable>` / `<text-input>` /
|
|
4
|
+
// `<switch>` carry its machine; an unregistered tag commits inert. Every adapter needs the same
|
|
5
|
+
// fourteen calls, so they live here once — an adapter's own `src/register.ts` is a single bare
|
|
6
|
+
// `import '@symbiote-native/components/register';`.
|
|
7
|
+
//
|
|
8
|
+
// WHY A SIDE-EFFECT MODULE AND NOT A BARREL EXPORT. Metro turns on `inlineRequires` for PRODUCTION
|
|
9
|
+
// only: it moves a `require` down to the first place its binding is used as a VALUE, and
|
|
10
|
+
// `export { X } from './x'` compiles to a lazy getter. A registration reached only through a
|
|
11
|
+
// re-export therefore never evaluates in a Release build — invisible to tsc, to vitest, and to
|
|
12
|
+
// grepping the bundle. A bare `import` placed NEXT TO a re-export of the same specifier does not
|
|
13
|
+
// help either: Babel merges the two into one dependency and the merged dependency stays lazy.
|
|
14
|
+
// `register.test.ts` is what stops a later tidy-up from turning this back into an export.
|
|
15
|
+
import { registerActivityIndicatorBehavior } from './behaviors/activity-indicator';
|
|
16
|
+
import { registerButtonBehavior } from './behaviors/button.js';
|
|
17
|
+
import { registerImageBackgroundBehavior } from './behaviors/image-background.js';
|
|
18
|
+
import { registerImageBehavior } from './behaviors/image.js';
|
|
19
|
+
import { registerInputAccessoryViewBehavior } from './behaviors/input-accessory-view.js';
|
|
20
|
+
import { registerPressableBehavior } from './behaviors/pressable.js';
|
|
21
|
+
import { registerRefreshControlBehavior } from './behaviors/refresh-control.js';
|
|
22
|
+
import { registerScrollViewBehavior } from './behaviors/scroll-view';
|
|
23
|
+
import { registerSwitchBehavior } from './behaviors/switch.js';
|
|
24
|
+
import { registerTextInputBehavior } from './behaviors/text-input.js';
|
|
25
|
+
import { registerTouchableHighlightBehavior } from './behaviors/touchable-highlight.js';
|
|
26
|
+
import { registerTouchableNativeFeedbackBehavior } from './behaviors/touchable-native-feedback.js';
|
|
27
|
+
import { registerTouchableOpacityBehavior } from './behaviors/touchable-opacity.js';
|
|
28
|
+
import { registerTouchableWithoutFeedbackBehavior } from './behaviors/touchable-without-feedback.js';
|
|
29
|
+
registerPressableBehavior();
|
|
30
|
+
registerTouchableNativeFeedbackBehavior();
|
|
31
|
+
registerTouchableWithoutFeedbackBehavior();
|
|
32
|
+
// Their own tags rather than `pressable`: one node holds exactly one press machine, and each of
|
|
33
|
+
// these is a pressable PLUS a second machine — the opacity fade, the underlay show/hide.
|
|
34
|
+
registerTouchableOpacityBehavior();
|
|
35
|
+
registerTouchableHighlightBehavior();
|
|
36
|
+
// The whole subtree is the behavior's — RN's Button takes no children and builds
|
|
37
|
+
// touchable > view > text > raw text itself (Button.js:363-388).
|
|
38
|
+
registerButtonBehavior();
|
|
39
|
+
// Two nodes, both the behavior's: RN wraps its native spinner in a centering View
|
|
40
|
+
// (ActivityIndicator.js:112), so the tag is that View and `buildStructure` builds the spinner.
|
|
41
|
+
registerActivityIndicatorBehavior();
|
|
42
|
+
registerTextInputBehavior();
|
|
43
|
+
registerSwitchBehavior();
|
|
44
|
+
registerRefreshControlBehavior();
|
|
45
|
+
// Fold-only, both of them: no node of their own, just the prop fold the wrapper used to run.
|
|
46
|
+
registerImageBehavior();
|
|
47
|
+
registerInputAccessoryViewBehavior();
|
|
48
|
+
registerImageBackgroundBehavior();
|
|
49
|
+
// The ENGINE is the single owner of a ScrollView's content node: `buildStructure` builds the
|
|
50
|
+
// `RCTScrollContentView`, `slotProps` carries `contentContainerStyle` onto it, the claim on a
|
|
51
|
+
// `refresh-control` child places it per platform, and the sticky seam is
|
|
52
|
+
// `behaviors/scroll-view/sticky.ts`. EXACTLY ONE THING MAY BUILD THAT NODE — a second owner is a
|
|
53
|
+
// silent `RCTScrollContentView` inside the first, which each adapter's
|
|
54
|
+
// `scroll-view-content-owner` test is what guards.
|
|
55
|
+
registerScrollViewBehavior();
|
|
@@ -16,6 +16,10 @@ export declare function splitLayoutProps(style: IStyleProp<IViewStyle> | undefin
|
|
|
16
16
|
outer: Record<string, unknown>;
|
|
17
17
|
inner: Record<string, unknown>;
|
|
18
18
|
};
|
|
19
|
+
export declare function splitScrollViewStyle(base: IStyleProp<IViewStyle> | undefined, style: unknown): {
|
|
20
|
+
outer: IStyleProp<IViewStyle>;
|
|
21
|
+
inner: IStyleProp<IViewStyle>;
|
|
22
|
+
};
|
|
19
23
|
export { isSymbioteEvent };
|
|
20
24
|
export declare function forwardScrollEvent(handler: IScrollHandler, args: readonly unknown[]): void;
|
|
21
25
|
export declare function buildScrollViewHandle(getNode: () => ISymbioteNode | null): IScrollViewHandle;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// the Android RefreshControl wrap, the scroll-event guard/forwarder, and the native sticky
|
|
4
4
|
// scroll-attach are all platform- and framework-invariant, so they live here. The adapter
|
|
5
5
|
// supplies the lifecycle (the node getter, the effect) and re-exports these.
|
|
6
|
-
import { attachNativeEvent,
|
|
6
|
+
import { attachNativeEvent, dlog, flattenStyle, isSymbioteEvent, } from '@symbiote-native/engine';
|
|
7
7
|
// RN's splitLayoutProps key partition (StyleSheet/splitLayoutProps.js): the LAYOUT keys
|
|
8
8
|
// that belong on the OUTER box when a layout-affecting wrapper sits between the laid-out
|
|
9
9
|
// frame and the visual content. Everything NOT in this set (background*, padding*, border*,
|
|
@@ -58,6 +58,24 @@ export function splitLayoutProps(style) {
|
|
|
58
58
|
}
|
|
59
59
|
return { outer, inner };
|
|
60
60
|
}
|
|
61
|
+
// The whole Android wrap style decision: the layout/visual split, AND the axis base composed onto
|
|
62
|
+
// BOTH boxes. RN does the second half too (`StyleSheet.compose(baseStyle, outer)` beside
|
|
63
|
+
// `compose(baseStyle, inner)`, ScrollView.js:1856), and every adapter had dropped it from the
|
|
64
|
+
// wrapper — so an AndroidSwipeRefreshLayout with no explicit user layout style lost `flexGrow: 1`
|
|
65
|
+
// and collapsed to its content height inside a flex parent, where RN's grows.
|
|
66
|
+
//
|
|
67
|
+
// One function rather than five call sites composing `[base, outer]` by hand, because that is what
|
|
68
|
+
// the last one drifted into: a fold written inline is invisible to
|
|
69
|
+
// `tests/lowered-primitive-fold-parity.test.ts`, whose oracle is shared value imports.
|
|
70
|
+
// `style` is `unknown` rather than `IStyleProp`, because a `payloadFold` reads it off an untyped
|
|
71
|
+
// props bag and `flattenStyle` — the only thing that touches it here — already takes `unknown`.
|
|
72
|
+
// Narrowing it would buy a guard at every fold call site and no safety.
|
|
73
|
+
export function splitScrollViewStyle(base, style) {
|
|
74
|
+
const { outer, inner } = splitLayoutProps(flattenStyle(style));
|
|
75
|
+
// Base UNDER the split half on both, so an explicit user value still wins — the same order the
|
|
76
|
+
// unwrapped scroll view composes.
|
|
77
|
+
return { outer: [base, outer], inner: [base, inner] };
|
|
78
|
+
}
|
|
61
79
|
// Re-exported so the package barrel (index.ts) can still export this guard to
|
|
62
80
|
// '@symbiote-native/components' callers, now that it lives in the engine, next to ISymbioteEvent.
|
|
63
81
|
export { isSymbioteEvent };
|
|
@@ -69,42 +87,23 @@ export function forwardScrollEvent(handler, args) {
|
|
|
69
87
|
if (isSymbioteEvent(first))
|
|
70
88
|
handler(first);
|
|
71
89
|
}
|
|
72
|
-
// The imperative handle is identical across platforms
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
//
|
|
90
|
+
// The imperative handle is identical across platforms — only the surrounding element assembly
|
|
91
|
+
// diverges (iOS sibling RefreshControl vs Android wrap) — so it is built once here and both
|
|
92
|
+
// platform files back it with their scroll node getter.
|
|
93
|
+
//
|
|
94
|
+
// It DELEGATES to the node's own methods rather than dispatching commands itself. The commands and
|
|
95
|
+
// their defaults live on `ISymbioteNode` because a LOWERED ScrollView hands the app its engine
|
|
96
|
+
// node directly, with no wrapper to build a handle: two implementations would let `scrollTo()` with
|
|
97
|
+
// no argument mean one thing through a ref and another through a tag, and nothing would report it.
|
|
77
98
|
//
|
|
78
99
|
// `getNode` is a LAZY getter (React `() => ref.current`, Vue `() => nodeRef.value`), read on
|
|
79
100
|
// every call, NOT the node captured once. The node is null at mount and only set after the
|
|
80
101
|
// element commits, so an eager capture would freeze `null` and every command would no-op.
|
|
81
102
|
export function buildScrollViewHandle(getNode) {
|
|
82
103
|
return {
|
|
83
|
-
scrollTo: (options) =>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return;
|
|
87
|
-
const x = options?.x ?? 0;
|
|
88
|
-
const y = options?.y ?? 0;
|
|
89
|
-
const animated = options?.animated ?? true;
|
|
90
|
-
dlog(`ScrollView.scrollTo x=${x} y=${y} animated=${animated}`);
|
|
91
|
-
dispatchViewCommand(node, 'scrollTo', [x, y, animated]);
|
|
92
|
-
},
|
|
93
|
-
scrollToEnd: (options) => {
|
|
94
|
-
const node = getNode();
|
|
95
|
-
if (node === null)
|
|
96
|
-
return;
|
|
97
|
-
const animated = options?.animated ?? true;
|
|
98
|
-
dlog(`ScrollView.scrollToEnd animated=${animated}`);
|
|
99
|
-
dispatchViewCommand(node, 'scrollToEnd', [animated]);
|
|
100
|
-
},
|
|
101
|
-
flashScrollIndicators: () => {
|
|
102
|
-
const node = getNode();
|
|
103
|
-
if (node === null)
|
|
104
|
-
return;
|
|
105
|
-
dlog('ScrollView.flashScrollIndicators');
|
|
106
|
-
dispatchViewCommand(node, 'flashScrollIndicators', []);
|
|
107
|
-
},
|
|
104
|
+
scrollTo: (options) => getNode()?.scrollTo(options),
|
|
105
|
+
scrollToEnd: (options) => getNode()?.scrollToEnd(options),
|
|
106
|
+
flashScrollIndicators: () => getNode()?.flashScrollIndicators(),
|
|
108
107
|
getScrollNode: () => getNode(),
|
|
109
108
|
};
|
|
110
109
|
}
|
|
@@ -53,6 +53,9 @@ export type IFoldedTextInputProps = {
|
|
|
53
53
|
showSoftInputOnFocus: boolean | undefined;
|
|
54
54
|
};
|
|
55
55
|
export declare function resolveTextInputProps(input: ITextInputFoldInput): IFoldedTextInputProps;
|
|
56
|
+
export type ITextInputChangeEvent = ISymbioteEvent & {
|
|
57
|
+
text: string;
|
|
58
|
+
};
|
|
56
59
|
export type ITextInputProps = IAccessibilityProps & IAriaProps & {
|
|
57
60
|
value?: string;
|
|
58
61
|
defaultValue?: string;
|
|
@@ -86,7 +89,7 @@ export type ITextInputProps = IAccessibilityProps & IAriaProps & {
|
|
|
86
89
|
underlineColorAndroid?: string;
|
|
87
90
|
inputAccessoryViewID?: string;
|
|
88
91
|
style?: ITextStyle;
|
|
89
|
-
onValueChange?: (
|
|
92
|
+
onValueChange?: (event: ITextInputChangeEvent) => void;
|
|
90
93
|
onFocus?: ITextInputEventHandler;
|
|
91
94
|
onBlur?: ITextInputEventHandler;
|
|
92
95
|
onEndEditing?: ITextInputEventHandler;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ITextStyle, ISymbioteEvent } from '@symbiote-native/engine';
|
|
1
|
+
import type { ITextStyle, IViewStyle, ISymbioteEvent } from '@symbiote-native/engine';
|
|
2
2
|
import type { IAccessibilityProps, IAriaProps } from '../accessibility-props';
|
|
3
3
|
export interface IButtonProps extends IAccessibilityProps, IAriaProps {
|
|
4
4
|
title: string;
|
|
@@ -16,4 +16,39 @@ export interface IButtonProps extends IAccessibilityProps, IAriaProps {
|
|
|
16
16
|
}
|
|
17
17
|
export declare const BUTTON_ACCESSIBILITY_ROLE = "button";
|
|
18
18
|
export declare const buttonTextStyle: ITextStyle;
|
|
19
|
+
export declare const buttonViewStyle: IViewStyle;
|
|
20
|
+
/**
|
|
21
|
+
* The label style with `color` and `disabled` folded in.
|
|
22
|
+
*
|
|
23
|
+
* `color` tints the TEXT on iOS and the BUTTON on Android (Button.js:318-324), so on Android this
|
|
24
|
+
* ignores it — see `resolveButtonViewStyle`, which is where it lands there. `disabled` wins over
|
|
25
|
+
* `color` on both, because RN pushes `textDisabled` after the tint.
|
|
26
|
+
*/
|
|
19
27
|
export declare function resolveButtonTextStyle(color: string | undefined, disabled: boolean | undefined): ITextStyle;
|
|
28
|
+
/**
|
|
29
|
+
* The inner view's style with `color` and `disabled` folded in — `{}` on iOS in every combination,
|
|
30
|
+
* which is RN's own answer there and the reason the node looked droppable.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveButtonViewStyle(color: string | undefined, disabled: boolean | undefined): IViewStyle;
|
|
33
|
+
/**
|
|
34
|
+
* The label as it is rendered: UPPERCASE on Android (Button.js:352-353).
|
|
35
|
+
*
|
|
36
|
+
* RN also asserts the title is a string one line above. Not reproduced: the assert is a dev-only
|
|
37
|
+
* `invariant`, and every adapter here types `title: string`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveButtonTitle(title: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the button is disabled, which `aria-disabled` may decide on its own.
|
|
42
|
+
*
|
|
43
|
+
* Button.js:337-338 — `props.disabled != null ? props.disabled : accessibilityState.disabled`. The
|
|
44
|
+
* engine already folds `aria-disabled` into the committed `accessibilityState`, but that fold is a
|
|
45
|
+
* PAYLOAD fold: it cannot suppress the press or grey the label, which is what this is for.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveButtonDisabled(disabled: boolean | undefined, ariaDisabled: boolean | undefined, accessibilityState: {
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
} | undefined): boolean | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Button.js:356-359 — `'no'` becomes `'no-hide-descendants'`, so the label inside cannot take
|
|
52
|
+
* focus separately from the button that contains it.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveButtonImportantForAccessibility(value: IAccessibilityProps['importantForAccessibility']): IAccessibilityProps['importantForAccessibility'];
|