@symbiote-native/components 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +10 -2
  2. package/build/accessibility-props.js +2 -1
  3. package/build/bootstrap/index.js +1 -1
  4. package/build/component-names/index.android.js +1 -1
  5. package/build/component-names/index.ios.js +1 -1
  6. package/build/component-names/shared.js +4 -1
  7. package/build/descriptor.d.ts +8 -0
  8. package/build/descriptor.js +27 -0
  9. package/build/index.d.ts +19 -11
  10. package/build/index.js +12 -5
  11. package/build/scroll-view-commands.js +5 -1
  12. package/build/state/pressable.js +13 -3
  13. package/build/state/sticky-header-reducer.d.ts +1 -0
  14. package/build/state/sticky-header-reducer.js +97 -5
  15. package/build/state/switch.js +1 -1
  16. package/build/state/text-input.d.ts +2 -1
  17. package/build/state/text-input.js +35 -8
  18. package/build/state/touchable.d.ts +30 -1
  19. package/build/state/touchable.js +94 -5
  20. package/build/state/virtualized-list-diagnostics.d.ts +31 -0
  21. package/build/state/virtualized-list-diagnostics.js +33 -0
  22. package/build/state/virtualized-list-reducer.d.ts +14 -0
  23. package/build/state/virtualized-list-reducer.js +179 -45
  24. package/build/state/virtualized-list.d.ts +7 -2
  25. package/build/state/virtualized-list.js +178 -37
  26. package/build/text-props.d.ts +9 -0
  27. package/build/text-props.js +24 -0
  28. package/build/view/render-activity-indicator.js +11 -3
  29. package/build/view/render-button.js +3 -4
  30. package/build/view/render-image/index.js +13 -3
  31. package/build/view/render-input-accessory-view.js +5 -2
  32. package/build/view/render-keyboard-avoiding-view.d.ts +14 -2
  33. package/build/view/render-keyboard-avoiding-view.js +52 -6
  34. package/build/view/render-modal.js +4 -2
  35. package/build/view/render-pressable/index.js +3 -1
  36. package/build/view/render-scroll-sticky.js +1 -1
  37. package/build/view/render-scroll-view.js +9 -3
  38. package/build/view/render-switch.js +4 -1
  39. package/build/view/render-touchable-highlight.d.ts +11 -1
  40. package/build/view/render-touchable-highlight.js +11 -10
  41. package/build/view/render-touchable-native-feedback.js +5 -1
  42. package/package.json +2 -2
  43. package/build/state/scroll-routing-handle/index.d.ts +0 -10
  44. package/build/state/scroll-routing-handle/index.js +0 -6
  45. package/build/view/layout-event/index.d.ts +0 -2
  46. package/build/view/layout-event/index.js +0 -12
@@ -26,7 +26,7 @@ export function resolveDecelerationRate(rate) {
26
26
  // select() types as `number | undefined`; the always-present `default` makes the
27
27
  // `??` fallback unreachable, but it narrows the return to a plain `number` (no cast).
28
28
  if (rate === 'normal')
29
- return Platform.select({ ios: 0.998, android: 0.985, default: 0.998 }) ?? 0.998;
29
+ return (Platform.select({ ios: 0.998, android: 0.985, default: 0.998 }) ?? 0.998);
30
30
  return Platform.select({ ios: 0.99, android: 0.9, default: 0.99 }) ?? 0.99;
31
31
  }
32
32
  // RN applies a base style to the scroll-view NODE itself, per axis (ScrollView.js
@@ -69,7 +69,12 @@ export function selectScrollIntrinsics(isHorizontal, contentContainerStyle) {
69
69
  const contentStyle = isHorizontal
70
70
  ? [contentContainerStyle, { flexDirection: 'row' }]
71
71
  : contentContainerStyle;
72
- return { scrollViewIntrinsic, contentIntrinsic, scrollViewBaseStyle, contentStyle };
72
+ return {
73
+ scrollViewIntrinsic,
74
+ contentIntrinsic,
75
+ scrollViewBaseStyle,
76
+ contentStyle,
77
+ };
73
78
  }
74
79
  // When sticky headers are active the scroll offset must reach the AnimatedValue; RN raises the scroll
75
80
  // event rate for it (ScrollView.js:1798): throttle 1 on the native driver (it can afford every frame),
@@ -81,7 +86,8 @@ export function resolveScrollForwarding(inputs) {
81
86
  // maintainVisibleContentPosition (and Android snapToAlignment) anchor against MOUNTED cell views;
82
87
  // Android Fabric view-flattens layout-only cells away, so RN keeps them as real views with
83
88
  // collapsableChildren={false} on the content container (ScrollView.js preserveChildren). No-op on iOS.
84
- const collapsableChildren = inputs.maintainVisibleContentPosition !== undefined || inputs.snapToAlignment !== undefined;
89
+ const collapsableChildren = inputs.maintainVisibleContentPosition !== undefined ||
90
+ inputs.snapToAlignment !== undefined;
85
91
  if (!inputs.hasStickyHeaders) {
86
92
  return {
87
93
  mode: 'plain',
@@ -14,7 +14,10 @@ const IOS_BACKGROUND_BORDER_RADIUS = 16;
14
14
  function foldIosBackground(style, color) {
15
15
  if (color === undefined)
16
16
  return style;
17
- return [style, { backgroundColor: color, borderRadius: IOS_BACKGROUND_BORDER_RADIUS }];
17
+ return [
18
+ style,
19
+ { backgroundColor: color, borderRadius: IOS_BACKGROUND_BORDER_RADIUS },
20
+ ];
18
21
  }
19
22
  export function renderSwitch(view, platform) {
20
23
  dlog(`Switch render value=${view.value} disabled=${String(view.disabled)}`);
@@ -1,2 +1,12 @@
1
1
  import type { IViewStyle } from '@symbiote-native/engine';
2
- export declare function highlightPressedStyle<TStyle>(pressed: boolean, style: TStyle, underlayColor: string, activeOpacity: number): TStyle | [TStyle, IViewStyle];
2
+ export interface ITouchableHighlightExtraStyles {
3
+ underlay: IViewStyle;
4
+ child: IViewStyle;
5
+ }
6
+ export interface ITouchableHighlightUnderlayView {
7
+ shown: boolean;
8
+ hasPressHandler: boolean;
9
+ underlayColor?: string;
10
+ activeOpacity?: number;
11
+ }
12
+ export declare function resolveHighlightExtraStyles(view: ITouchableHighlightUnderlayView): ITouchableHighlightExtraStyles | undefined;
@@ -1,12 +1,13 @@
1
1
  // TouchableHighlight underlay: the shared render decision (framework-agnostic). RN drives the
2
- // highlight with setState (not Animated) — while pressed it paints underlayColor + lowers the child
3
- // opacity, at rest it is the bare style (TouchableHighlight.js). This 3-line gating was triplicated
4
- // verbatim across adapters; it lives here once, prop-driven. Each adapter passes its own resolved
5
- // style base (React the raw style, Angular the anchor+style array, Vue the untyped attrs style) plus
6
- // the live `pressed`, so the base is generic — the overlay is layered on top when pressed.
7
- export function highlightPressedStyle(pressed, style, underlayColor, activeOpacity) {
8
- if (!pressed)
9
- return style;
10
- const overlay = { backgroundColor: underlayColor, opacity: activeOpacity };
11
- return [style, overlay];
2
+ // highlight with setState, not Animated — while shown it paints underlayColor and lowers the child
3
+ // opacity; at rest it is the bare style (TouchableHighlight.js).
4
+ import { DEFAULT_HIGHLIGHT_CHILD_OPACITY, DEFAULT_UNDERLAY_COLOR, } from '../state/touchable.js';
5
+ // undefined = paint nothing extra, which is RN's `extraStyles: null` state.
6
+ export function resolveHighlightExtraStyles(view) {
7
+ if (!view.shown || !view.hasPressHandler)
8
+ return undefined;
9
+ return {
10
+ underlay: { backgroundColor: view.underlayColor ?? DEFAULT_UNDERLAY_COLOR },
11
+ child: { opacity: view.activeOpacity ?? DEFAULT_HIGHLIGHT_CHILD_OPACITY },
12
+ };
12
13
  }
@@ -14,7 +14,11 @@ export function canUseNativeForeground() {
14
14
  Platform.Version >= ANDROID_FOREGROUND_MIN_VERSION);
15
15
  }
16
16
  export function selectableBackground(rippleRadius) {
17
- return { type: 'ThemeAttrAndroid', attribute: 'selectableItemBackground', rippleRadius };
17
+ return {
18
+ type: 'ThemeAttrAndroid',
19
+ attribute: 'selectableItemBackground',
20
+ rippleRadius,
21
+ };
18
22
  }
19
23
  export function selectableBackgroundBorderless(rippleRadius) {
20
24
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/components",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Framework-agnostic component logic (state machines + render functions) for SymbioteNative — written once, inherited by every adapter (React, Vue, Angular, ...).",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "^26.0.0",
42
- "@symbiote-native/engine": "0.1.7"
42
+ "@symbiote-native/engine": "0.3.0"
43
43
  },
44
44
  "scripts": {
45
45
  "typecheck": "tsc --build",
@@ -1,10 +0,0 @@
1
- import type { ISymbioteNode } from '@symbiote-native/engine';
2
- import type { IScrollViewHandle } from '../../scroll-view-commands';
3
- export interface IScrollRoutingHandle {
4
- flashScrollIndicators(): void;
5
- getNativeScrollRef(): IScrollViewHandle | null;
6
- getScrollableNode(): IScrollViewHandle | null;
7
- getScrollResponder(): IScrollViewHandle | null;
8
- getScrollNode(): ISymbioteNode | null;
9
- recordInteraction(): void;
10
- }
@@ -1,6 +0,0 @@
1
- // The inner-scroll routing tail every windowed-list imperative handle exposes
2
- // (VirtualizedList, VirtualizedSectionList, and via those FlatList/SectionList). Each
3
- // method forwards straight to the underlying ScrollView's own handle/node; neither list
4
- // adds behavior of its own, so the 6 members live here once and both list handle types
5
- // extend this instead of hand-duplicating (and risking drift in) the signatures.
6
- export {};
@@ -1,2 +0,0 @@
1
- import type { ISymbioteEvent } from '@symbiote-native/engine';
2
- export declare function readLayoutField(event: ISymbioteEvent, key: 'width' | 'height' | 'y'): number | undefined;
@@ -1,12 +0,0 @@
1
- // Shared across render-scroll-view's content/frame dimension read (width/height) and
2
- // render-scroll-sticky's header position read (y/height): both pull a single numeric field out of
3
- // an onLayout event's nativeEvent.layout. SymbioteEvent.nativeEvent is Record<string, unknown>, so
4
- // the layout box and the requested field are narrowed at runtime, no cast. A malformed event
5
- // yields undefined (no-op).
6
- export function readLayoutField(event, key) {
7
- const layout = event.nativeEvent.layout;
8
- if (typeof layout !== 'object' || layout === null)
9
- return undefined;
10
- const value = Reflect.get(layout, key);
11
- return typeof value === 'number' ? value : undefined;
12
- }